Cataclysm BN
map Class Reference

Manage and cache data about a part of the map. More...

#include <map.h>

Inheritance diagram for map:
tinymap fake_map

Classes

struct  apparent_light_info
 

Public Member Functions

 map (int mapsize=MAPSIZE, bool zlev=false)
 
 map (bool zlev)
 
virtual ~map ()
 
mapoperator= (const map &)=delete
 
mapoperator= (map &&)
 
void set_transparency_cache_dirty (const int zlev)
 Sets a dirty flag on the a given cache. More...
 
void set_transparency_cache_dirty (const tripoint &p)
 
void set_seen_cache_dirty (const tripoint change_location)
 
void set_seen_cache_dirty (const int zlevel)
 
void set_outside_cache_dirty (const int zlev)
 
void set_floor_cache_dirty (const int zlev)
 
void set_suspension_cache_dirty (const int zlev)
 
void set_pathfinding_cache_dirty (int zlev)
 
void set_memory_seen_cache_dirty (const tripoint &p)
 
void invalidate_map_cache (const int zlev)
 
bool check_seen_cache (const tripoint &p) const
 
bool check_and_set_seen_cache (const tripoint &p) const
 
void on_vehicle_moved (int smz)
 Callback invoked when a vehicle has moved. More...
 
lit_level apparent_light_at (const tripoint &p, const visibility_variables &cache) const
 Determine the visible light level for a tile, based on light_at for the tile, vision distance, etc. More...
 
visibility_type get_visibility (lit_level ll, const visibility_variables &cache) const
 
std::tuple< maptile, maptile, maptileget_wind_blockers (const int &winddirection, const tripoint &pos)
 
void draw (const catacurses::window &w, const tripoint &center)
 Draw a visible part of the map into w. More...
 
void drawsq (const catacurses::window &w, const tripoint &p, const drawsq_params &params) const
 Draw the map tile at the given coordinate. More...
 
void save ()
 Add currently loaded submaps (in grid) to the mapbuffer. More...
 
void load (const tripoint &w, bool update_vehicles, bool pump_events=false)
 Load submaps into grid. More...
 
void load (const tripoint_abs_sm &w, bool update_vehicles, bool pump_events=false)
 
void shift (const point &s)
 Shift the map along the vector s. More...
 
void vertical_shift (int newz)
 Moves the map vertically to (not by!) newz. More...
 
void clear_spawns ()
 
void clear_traps ()
 
maptile maptile_at (const tripoint &p) const
 
maptile maptile_at (const tripoint &p)
 
int move_cost (const tripoint &p, const vehicle *ignored_vehicle=nullptr) const
 Calculate the cost to move past the tile at p. More...
 
int move_cost (const point &p, const vehicle *ignored_vehicle=nullptr) const
 
bool impassable (const tripoint &p) const
 
bool impassable (const point &p) const
 
bool passable (const tripoint &p) const
 
bool passable (const point &p) const
 
bool is_wall_adjacent (const tripoint &center) const
 
int move_cost_ter_furn (const tripoint &p) const
 Similar behavior to move_cost(), but ignores vehicles. More...
 
int move_cost_ter_furn (const point &p) const
 
bool impassable_ter_furn (const tripoint &p) const
 
bool passable_ter_furn (const tripoint &p) const
 
int combined_movecost (const tripoint &from, const tripoint &to, const vehicle *ignored_vehicle=nullptr, int modifier=0, bool flying=false, bool via_ramp=false) const
 Cost to move out of one tile and into the next. More...
 
bool valid_move (const tripoint &from, const tripoint &to, bool bash=false, bool flying=false, bool via_ramp=false) const
 Returns true if a creature could walk from from to to in one step. More...
 
double ranged_target_size (const tripoint &p) const
 Size of map objects at p for purposes of ranged combat. More...
 
bool sees (const tripoint &F, const tripoint &T, int range) const
 Returns whether F sees T with a view range of range. More...
 
int obstacle_coverage (const tripoint &loc1, const tripoint &loc2) const
 Returns coverage of target in relation to the observer. More...
 
int coverage (const tripoint &p) const
 Returns coverage value of the tile. More...
 
bool clear_path (const tripoint &f, const tripoint &t, int range, int cost_min, int cost_max) const
 Check whether there's a direct line of sight between F and T with the additional movecost restraints. More...
 
bool obstructed_by_vehicle_rotation (const tripoint &from, const tripoint &to) const
 Checks if a rotated vehicle is blocking diagonal movement, tripoints must be adjacent. More...
 
bool obscured_by_vehicle_rotation (const tripoint &from, const tripoint &to) const
 Checks if a rotated vehicle is blocking diagonal vision, tripoints must be adjacent. More...
 
void reachable_flood_steps (std::vector< tripoint > &reachable_pts, const tripoint &f, int range, int cost_min, int cost_max) const
 Populates a vector of points that are reachable within a number of steps from a point. More...
 
std::vector< tripointfind_clear_path (const tripoint &source, const tripoint &destination) const
 Iteratively tries Bresenham lines with different biases until it finds a clear line or decides there isn't one. More...
 
bool accessible_items (const tripoint &t) const
 Check whether the player can access the items located . More...
 
std::vector< tripointget_dir_circle (const tripoint &f, const tripoint &t) const
 Calculate next search points surrounding the current position. More...
 
std::vector< tripointroute (const tripoint &f, const tripoint &t, const pathfinding_settings &settings, const std::set< tripoint > &pre_closed={{ }}) const
 Calculate the best path using A*. More...
 
VehicleList get_vehicles ()
 
void add_vehicle_to_cache (vehicle *)
 
void clear_vehicle_point_from_cache (vehicle *veh, const tripoint &pt)
 
void update_vehicle_cache (vehicle *, int old_zlevel)
 
void reset_vehicle_cache ()
 
void clear_vehicle_cache ()
 
void clear_vehicle_list (int zlev)
 
void update_vehicle_list (const submap *to, int zlev)
 
bool check_vehicle_zones (int zlev)
 
std::vector< zone_data * > get_vehicle_zones (int zlev)
 
void register_vehicle_zone (vehicle *, int zlev)
 
bool deregister_vehicle_zone (zone_data &zone)
 
std::unique_ptr< vehicledetach_vehicle (vehicle *veh)
 
void destroy_vehicle (vehicle *veh)
 
void vehmove ()
 
bool vehproceed (VehicleList &vehicle_list)
 
VehicleList get_vehicles (const tripoint &start, const tripoint &end)
 
optional_vpart_position veh_at (const tripoint &p) const
 Checks if tile is occupied by vehicle and by which part. More...
 
vehicleveh_at_internal (const tripoint &p, int &part_num)
 
const vehicleveh_at_internal (const tripoint &p, int &part_num) const
 
void board_vehicle (const tripoint &p, player *pl)
 
void unboard_vehicle (const vpart_reference &, Character *passenger, bool dead_passenger=false)
 
void unboard_vehicle (const tripoint &p, bool dead_passenger=false)
 
bool displace_vehicle (vehicle &veh, const tripoint &dp)
 
void shift_vehicle_z (vehicle &veh, int z_shift)
 
bool displace_water (const tripoint &dp)
 
float vehicle_wheel_traction (const vehicle &veh, bool ignore_movement_modifiers=false) const
 
float vehicle_vehicle_collision (vehicle &veh, vehicle &veh2, const std::vector< veh_collision > &collisions)
 
units::angle shake_vehicle (vehicle &veh, int velocity_before, units::angle direction)
 
vehiclemove_vehicle (vehicle &veh, const tripoint &dp, const tileray &facing)
 
void set (const tripoint &p, const ter_id &new_terrain, const furn_id &new_furniture)
 
void set (const point &p, const ter_id &new_terrain, const furn_id &new_furniture)
 
std::string name (const tripoint &p)
 
std::string name (const point &p)
 
std::string disp_name (const tripoint &p)
 
std::string obstacle_name (const tripoint &p)
 Returns the name of the obstacle at p that might be blocking movement/projectiles/etc. More...
 
bool has_furn (const tripoint &p) const
 
bool has_furn (const point &p) const
 
furn_id furn (const tripoint &p) const
 
furn_id furn (const point &p) const
 
void furn_set (const tripoint &p, const furn_id &new_furniture, cata::poly_serialized< active_tile_data > new_active=nullptr)
 Sets the furniture at given position. More...
 
void furn_set (const point &p, const furn_id &new_furniture)
 
std::string furnname (const tripoint &p)
 
std::string furnname (const point &p)
 
bool can_move_furniture (const tripoint &pos, player *p=nullptr)
 
ter_id ter (const tripoint &p) const
 
ter_id ter (const point &p) const
 
uint8_t get_known_connections (const tripoint &p, int connect_group, const std::map< tripoint, ter_id > &override={}) const
 
const harvest_idget_harvest (const tripoint &p) const
 Returns the full harvest list, for spawning. More...
 
const std::set< std::string > & get_harvest_names (const tripoint &p) const
 Returns names of the items that would be dropped. More...
 
ter_id get_ter_transforms_into (const tripoint &p) const
 
furn_id get_furn_transforms_into (const tripoint &p) const
 
bool ter_set (const tripoint &p, const ter_id &new_terrain)
 
bool ter_set (const point &p, const ter_id &new_terrain)
 
std::string tername (const tripoint &p) const
 
std::string tername (const point &p) const
 
bool has_nearby_fire (const tripoint &p, int radius=1)
 
bool has_nearby_table (const tripoint &p, int radius=1)
 Check whether a table/workbench/vehicle kitchen or other flat surface is nearby that could be used for crafting or eating. More...
 
bool has_nearby_chair (const tripoint &p, int radius=1)
 Check whether a chair or vehicle seat is nearby. More...
 
bool sees_some_items (const tripoint &p, const Creature &who) const
 Check if creature can see some items at p. More...
 
bool sees_some_items (const tripoint &p, const tripoint &from) const
 
bool could_see_items (const tripoint &p, const Creature &who) const
 Check if the creature could see items at p if there were any items. More...
 
bool could_see_items (const tripoint &p, const tripoint &from) const
 
bool has_items (const tripoint &p) const
 Checks for existence of items. More...
 
void examine (Character &p, const tripoint &pos)
 Calls the examine function of furniture or terrain at given tile, for given character. More...
 
bool is_harvestable (const tripoint &pos) const
 Returns true if point at pos is harvestable right now, with no extra tools. More...
 
std::string features (const tripoint &p)
 
std::string features (const point &p)
 
bool has_flag (const std::string &flag, const tripoint &p) const
 
bool has_flag (const std::string &flag, const point &p) const
 
bool can_put_items (const tripoint &p) const
 
bool can_put_items (const point &p) const
 
bool can_put_items_ter_furn (const tripoint &p) const
 
bool can_put_items_ter_furn (const point &p) const
 
bool has_flag_ter (const std::string &flag, const tripoint &p) const
 
bool has_flag_ter (const std::string &flag, const point &p) const
 
bool has_flag_furn (const std::string &flag, const tripoint &p) const
 
bool has_flag_furn (const std::string &flag, const point &p) const
 
bool has_flag_vpart (const std::string &flag, const tripoint &p) const
 
bool has_flag_furn_or_vpart (const std::string &flag, const tripoint &p) const
 
bool has_flag_ter_or_furn (const std::string &flag, const tripoint &p) const
 
bool has_flag_ter_or_furn (const std::string &flag, const point &p) const
 
bool has_flag (ter_bitflags flag, const tripoint &p) const
 
bool has_flag (ter_bitflags flag, const point &p) const
 
bool has_flag_ter (ter_bitflags flag, const tripoint &p) const
 
bool has_flag_ter (ter_bitflags flag, const point &p) const
 
bool has_flag_furn (ter_bitflags flag, const tripoint &p) const
 
bool has_flag_furn (ter_bitflags flag, const point &p) const
 
bool has_flag_ter_or_furn (ter_bitflags flag, const tripoint &p) const
 
bool has_flag_ter_or_furn (ter_bitflags flag, const point &p) const
 
bool is_bashable (const tripoint &p, bool allow_floor=false) const
 Returns true if there is a bashable vehicle part or the furn/terrain is bashable at p. More...
 
bool is_bashable (const point &p) const
 
bool is_bashable_ter (const tripoint &p, bool allow_floor=false) const
 Returns true if the terrain at p is bashable. More...
 
bool is_bashable_ter (const point &p) const
 
bool is_bashable_furn (const tripoint &p) const
 Returns true if the furniture at p is bashable. More...
 
bool is_bashable_furn (const point &p) const
 
bool is_bashable_ter_furn (const tripoint &p, bool allow_floor=false) const
 Returns true if the furniture or terrain at p is bashable. More...
 
bool is_bashable_ter_furn (const point &p) const
 
int bash_strength (const tripoint &p, bool allow_floor=false) const
 Returns max_str of the furniture or terrain at p. More...
 
int bash_strength (const point &p) const
 
int bash_resistance (const tripoint &p, bool allow_floor=false) const
 Returns min_str of the furniture or terrain at p. More...
 
int bash_resistance (const point &p) const
 
int bash_rating (int str, const tripoint &p, bool allow_floor=false) const
 Returns a success rating from -1 to 10 for a given tile based on a set strength, used for AI movement planning Values roughly correspond to 10% increment chances of success on a given bash, rounded down. More...
 
int bash_rating (const int str, const point &p) const
 
void make_rubble (const tripoint &p, const furn_id &rubble_type, bool items, const ter_id &floor_type, bool overwrite=false)
 Generates rubble at the given location, if overwrite is true it just writes on top of what currently exists floor_type is only used if there is a non-bashable wall at the location or with overwrite = true. More...
 
void make_rubble (const tripoint &p, const furn_id &rubble_type, bool items)
 
void make_rubble (const tripoint &p)
 
bool is_outside (const tripoint &p) const
 
bool is_outside (const point &p) const
 
bool is_divable (const tripoint &p) const
 Returns whether or not the terrain at the given location can be dived into (by monsters that can swim or are aquatic or non-breathing). More...
 
bool is_divable (const point &p) const
 
bool is_water_shallow_current (const tripoint &p) const
 
bool is_water_shallow_current (const point &p) const
 
bool is_last_ter_wall (bool no_furn, const point &p, const point &max, direction dir) const
 Check if the last terrain is wall in direction NORTH, SOUTH, WEST or EAST. More...
 
bool tinder_at (const tripoint &p)
 Checks if there are any tinder flagged items on the tile. More...
 
bool flammable_items_at (const tripoint &p, int threshold=0)
 Checks if there are any flammable items on the tile. More...
 
bool is_flammable (const tripoint &p)
 Returns true if there is a flammable item or field or the furn/terrain is flammable at p. More...
 
point random_outdoor_tile ()
 
void draw_line_ter (const ter_id &type, const point &p1, const point &p2)
 
void draw_line_furn (const furn_id &type, const point &p1, const point &p2)
 
void draw_fill_background (const ter_id &type)
 
void draw_fill_background (ter_id(*f)())
 
void draw_fill_background (const weighted_int_list< ter_id > &f)
 
void draw_square_ter (const ter_id &type, const point &p1, const point &p2)
 
void draw_square_furn (const furn_id &type, const point &p1, const point &p2)
 
void draw_square_ter (ter_id(*f)(), const point &p1, const point &p2)
 
void draw_square_ter (const weighted_int_list< ter_id > &f, const point &p1, const point &p2)
 
void draw_rough_circle_ter (const ter_id &type, const point &p, int rad)
 
void draw_rough_circle_furn (const furn_id &type, const point &p, int rad)
 
void draw_circle_ter (const ter_id &type, const rl_vec2d &p, double rad)
 
void draw_circle_ter (const ter_id &type, const point &p, int rad)
 
void draw_circle_furn (const furn_id &type, const point &p, int rad)
 
void add_corpse (const tripoint &p)
 
void translate (const ter_id &from, const ter_id &to)
 
void translate_radius (const ter_id &from, const ter_id &to, float radi, const tripoint &p, bool same_submap=false, bool toggle_between=false)
 
bool close_door (const tripoint &p, bool inside, bool check_only)
 
bool open_door (const tripoint &p, bool inside, bool check_only=false)
 
void batter (const tripoint &p, int power, int tries=1, bool silent=false)
 bash a square for a set number of times at set power. More...
 
void destroy (const tripoint &p, bool silent=false)
 Keeps bashing a square until it can't be bashed anymore. More...
 
void destroy_furn (const tripoint &p, bool silent=false)
 Keeps bashing a square until there is no more furniture. More...
 
void crush (const tripoint &p)
 
void shoot (const tripoint &p, projectile &proj, bool hit_items)
 
int collapse_check (const tripoint &p)
 Checks if a square should collapse, returns the X for the one_in(X) collapse chance. More...
 
void collapse_at (const tripoint &p, bool silent, bool was_supporting=false, bool destroy_pos=true)
 Causes a collapse at p, such as from destroying a wall. More...
 
void propagate_suspension_check (const tripoint &point)
 Checks surrounding tiles for suspension, and has them check for collapse. More...
 
void collapse_invalid_suspension (const tripoint &point)
 Triggers a recursive collapse of suspended tiles based on their support validity. More...
 
bool is_suspension_valid (const tripoint &point)
 Checks the four orientations in which a suspended tile could be valid, and returns if the tile is valid. More...
 
void smash_items (const tripoint &p, int power, const std::string &cause_message, bool do_destroy)
 Tries to smash the items at the given tripoint. More...
 
bash_results bash (const tripoint &p, int str, bool silent=false, bool destroy=false, bool bash_floor=false, const vehicle *bashing_vehicle=nullptr)
 Returns a pair where first is whether anything was smashed and second is if it was destroyed. More...
 
bash_results bash_vehicle (const tripoint &p, const bash_params &params)
 
bash_results bash_ter_furn (const tripoint &p, const bash_params &params)
 
bool hit_with_acid (const tripoint &p)
 
bool hit_with_fire (const tripoint &p)
 
bool has_adjacent_furniture_with (const tripoint &p, const std::function< bool(const furn_t &)> &filter)
 Returns true if there is furniture for which filter returns true in a 1 tile radius of p. More...
 
bool mop_spills (const tripoint &p)
 Remove moppable fields/items at this location. More...
 
void decay_fields_and_scent (const time_duration &amount)
 Moved here from weather.cpp for speed. More...
 
std::string get_signage (const tripoint &p) const
 
void set_signage (const tripoint &p, const std::string &message) const
 
void delete_signage (const tripoint &p) const
 
int get_radiation (const tripoint &p) const
 
void set_radiation (const tripoint &p, int value)
 
void set_radiation (const point &p, const int value)
 
void adjust_radiation (const tripoint &p, int delta)
 Increment the radiation in the given tile by the given delta (decrement it if delta is negative) More...
 
void adjust_radiation (const point &p, const int delta)
 
int get_temperature (const tripoint &p) const
 
void set_temperature (const tripoint &p, int temperature)
 
void set_temperature (const point &p, int new_temperature)
 
std::vector< tripointcheck_submap_active_item_consistency ()
 
map_stack i_at (const tripoint &p)
 
map_stack i_at (const point &p)
 
item water_from (const tripoint &p)
 
void i_clear (const tripoint &p)
 
void i_clear (const point &p)
 
map_stack::iterator i_rem (const tripoint &p, map_stack::const_iterator it)
 
map_stack::iterator i_rem (const point &location, map_stack::const_iterator it)
 
void i_rem (const tripoint &p, item *it)
 
void i_rem (const point &p, item *it)
 
void spawn_artifact (const tripoint &p)
 
void spawn_natural_artifact (const tripoint &p, artifact_natural_property prop)
 
void spawn_item (const tripoint &p, const itype_id &type_id, unsigned quantity=1, int charges=0, const time_point &birthday=calendar::start_of_cataclysm, int damlevel=0)
 
void spawn_item (const point &p, const itype_id &type_id, unsigned quantity=1, int charges=0, const time_point &birthday=calendar::start_of_cataclysm, int damlevel=0)
 
void spawn_item (const tripoint &p, const std::string &type_id, unsigned quantity=1, int charges=0, const time_point &birthday=calendar::start_of_cataclysm, int damlevel=0)
 
void spawn_item (const point &p, const std::string &type_id, unsigned quantity=1, int charges=0, const time_point &birthday=calendar::start_of_cataclysm, int damlevel=0)
 
units::volume max_volume (const tripoint &p)
 
units::volume free_volume (const tripoint &p)
 
units::volume stored_volume (const tripoint &p)
 
itemadd_item_or_charges (const tripoint &pos, item obj, bool overflow=true)
 Adds an item to map tile or stacks charges. More...
 
itemadd_item_or_charges (const point &p, item obj, bool overflow=true)
 
itemadd_item (const tripoint &p, item new_item)
 Place an item on the map, despite the parameter name, this is not necessarily a new item. More...
 
void add_item (const point &p, item new_item)
 
itemspawn_an_item (const tripoint &p, item new_item, int charges, int damlevel)
 
void spawn_an_item (const point &p, item new_item, int charges, int damlevel)
 
void make_active (item_location &loc)
 Update an item's active status, for example when adding hot or perishable liquid to a container. More...
 
void update_lum (item_location &loc, bool add)
 Update luminosity before and after item's transformation. More...
 

Static Public Member Functions

static apparent_light_info apparent_light_helper (const level_cache &map_cache, const tripoint &p)
 Helper function for light claculation; exposed here for map editor. More...
 

Private Member Functions

maptile maptile_at_internal (const tripoint &p) const
 
maptile maptile_at_internal (const tripoint &p)
 
std::pair< tripoint, maptilemaptile_has_bounds (const tripoint &p, bool bounds_checked)
 
std::array< std::pair< tripoint, maptile >, 8 > get_neighbors (const tripoint &p)
 
void spread_gas (field_entry &cur, const tripoint &p, int percent_spread, const time_duration &outdoor_age_speedup, scent_block &sblk)
 
void create_hot_air (const tripoint &p, int intensity)
 
bool gas_can_spread_to (field_entry &cur, const tripoint &src, const tripoint &dst)
 
void gas_spread_to (field_entry &cur, maptile &dst, const tripoint &p)
 
int burn_body_part (player &u, field_entry &cur, body_part bp, int scale)
 
bool sees (const tripoint &F, const tripoint &T, int range, int &bresenham_slope) const
 Don't expose the slope adjust outside map functions. More...
 

Friends

class editmap
 
class visitable< map_cursor >
 

Consume items on the map

The functions here consume accessible items / item charges on the map or in vehicles around the player (whose positions is given as origin).

They return a list of copies of the consumed items (with the actually consumed charges in it). The quantity / amount parameter will be reduced by the number of items/charges removed. If all required items could be removed from the map, the quantity/amount will be 0, otherwise it will contain a positive value and the remaining items must be gathered from somewhere else.

enum  iteration_state { ITER_CONTINUE = 0 , ITER_SKIP_SUBMAP , ITER_SKIP_ZLEVEL , ITER_FINISH }
 Enum used by functors in function_over to control execution. More...
 
std::set< tripointsupport_cache_dirty
 
std::vector< submap * > grid
 The list of currently loaded submaps. More...
 
std::vector< std::vector< tripoint > > traplocs
 This vector contains an entry for each trap type, it has therefor the same size as the traplist vector. More...
 
std::vector< tripointfield_furn_locs
 Vector of tripoints containing active field-emitting furniture. More...
 
std::array< std::unique_ptr< level_cache >, OVERMAP_LAYERScaches
 Holds caches for visibility, light, transparency and vehicles. More...
 
std::array< std::unique_ptr< pathfinding_cache >, OVERMAP_LAYERSpathfinding_caches
 
std::set< tripointsubmaps_with_active_items
 Set of submaps that contain active items in absolute coordinates. More...
 
lru_cache< point, char > skew_vision_cache
 Cache of coordinate pairs recently checked for visibility. More...
 
VehicleList last_full_vehicle_list
 Vehicle list doesn't change often, but is pretty expensive. More...
 
bool last_full_vehicle_list_dirty = true
 
visibility_variables visibility_variables_cache
 
cata::optional< std::pair< tripoint, int > > max_populated_zlev = cata::nullopt
 
std::set< vehicle * > dirty_vehicle_list
 
int my_MAPSIZE
 
bool zlevels
 
vision_adjustment vision_transparency_cache [8] = { VISION_ADJUST_NONE }
 
tripoint abs_sub
 Absolute coordinates of first submap (get_submap_at(0,0)) This is in submap coordinates (see overmapbuffer for explanation). More...
 
std::list< itemuse_amount_square (const tripoint &p, const itype_id &type, int &quantity, const std::function< bool(const item &)> &filter=return_true< item >)
 
std::list< itemuse_amount (const tripoint &origin, int range, const itype_id &type, int &quantity, const std::function< bool(const item &)> &filter=return_true< item >)
 
std::list< itemuse_charges (const tripoint &origin, int range, const itype_id &type, int &quantity, const std::function< bool(const item &)> &filter=return_true< item >, basecamp *bcp=nullptr)
 
std::vector< item * > place_items (const item_group_id &loc, int chance, const tripoint &p1, const tripoint &p2, bool ongrass, const time_point &turn, int magazine=0, int ammo=0)
 Place items from item group in the rectangle f - t. More...
 
std::vector< item * > place_items (const item_group_id &loc, int chance, const point &p1, const point &p2, bool ongrass, const time_point &turn, int magazine=0, int ammo=0)
 
std::vector< item * > put_items_from_loc (const item_group_id &loc, const tripoint &p, const time_point &turn=calendar::start_of_cataclysm)
 Place items from an item group at p. More...
 
std::vector< item * > spawn_items (const tripoint &p, const std::vector< item > &new_items)
 
void spawn_items (const point &p, const std::vector< item > &new_items)
 
void create_anomaly (const tripoint &p, artifact_natural_property prop, bool create_rubble=true)
 
void create_anomaly (const point &cp, artifact_natural_property prop, bool create_rubble=true)
 
void partial_con_set (const tripoint &p, const partial_con &con)
 
void partial_con_remove (const tripoint &p)
 
partial_conpartial_con_at (const tripoint &p)
 
void trap_set (const tripoint &p, const trap_id &type)
 
const traptr_at (const tripoint &p) const
 
bool can_see_trap_at (const tripoint &p, const Character &c) const
 See trap::can_see, which is called for the trap here. More...
 
void disarm_trap (const tripoint &p)
 
void remove_trap (const tripoint &p)
 
const std::vector< tripoint > & get_furn_field_locations () const
 
const std::vector< tripoint > & trap_locations (const trap_id &type) const
 
void create_burnproducts (const tripoint &p, const item &fuel, const units::mass &burned_mass)
 
void process_fields ()
 
void process_fields_in_submap (submap *current_submap, const tripoint &submap_pos)
 
void creature_in_field (Creature &critter)
 Apply field effects to the creature when it's on a square with fields. More...
 
void creature_on_trap (Creature &critter, bool may_avoid=true)
 Apply trap effects to the creature, similar to creature_in_field. More...
 
const fieldfield_at (const tripoint &p) const
 Get the fields that are here. More...
 
fieldfield_at (const tripoint &p)
 Gets fields that are here. More...
 
time_duration get_field_age (const tripoint &p, const field_type_id &type) const
 Get the age of a field entry (field_entry::age), if there is no field of that type, returns -1_turns. More...
 
int get_field_intensity (const tripoint &p, const field_type_id &type) const
 Get the intensity of a field entry (field_entry::intensity), if there is no field of that type, returns 0. More...
 
time_duration mod_field_age (const tripoint &p, const field_type_id &type, const time_duration &offset)
 Increment/decrement age of field entry at point. More...
 
int mod_field_intensity (const tripoint &p, const field_type_id &type, int offset)
 Increment/decrement intensity of field entry at point, creating if not present, removing if intensity becomes 0. More...
 
time_duration set_field_age (const tripoint &p, const field_type_id &type, const time_duration &age, bool isoffset=false)
 Set age of field entry at point. More...
 
int set_field_intensity (const tripoint &p, const field_type_id &type, int new_intensity, bool isoffset=false)
 Set intensity of field entry at point, creating if not present, removing if intensity becomes 0. More...
 
field_entryget_field (const tripoint &p, const field_type_id &type)
 Get field of specific type at point. More...
 
bool dangerous_field_at (const tripoint &p)
 
bool add_field (const tripoint &p, const field_type_id &type_id, int intensity=INT_MAX, const time_duration &age=0_turns, bool hit_player=true)
 Add field entry at point, or set intensity if present. More...
 
void remove_field (const tripoint &p, const field_type_id &field_to_remove)
 Remove field entry at xy, ignored if the field entry is not present. More...
 
void add_splatter (const field_type_id &type, const tripoint &where, int intensity=1)
 
void add_splatter_trail (const field_type_id &type, const tripoint &from, const tripoint &to)
 
void add_splash (const field_type_id &type, const tripoint &center, int radius, int intensity)
 
void propagate_field (const tripoint &center, const field_type_id &type, int amount, int max_intensity=0)
 
void emit_field (const tripoint &pos, const emit_id &src, float mul=1.0f)
 Runs one cycle of emission src which may result in propagation of fields. More...
 
void scent_blockers (std::array< std::array< char, MAPSIZE_X >, MAPSIZE_Y > &scent_transfer, const point &min, const point &max)
 Build the map of scent-resistant tiles. More...
 
computercomputer_at (const tripoint &p)
 
computeradd_computer (const tripoint &p, const std::string &name, int security)
 
void add_camp (const tripoint_abs_omt &omt_pos, const std::string &name)
 
void remove_submap_camp (const tripoint &)
 
basecamp hoist_submap_camp (const tripoint &p)
 
bool point_within_camp (const tripoint &point_check) const
 
bool has_graffiti_at (const tripoint &p) const
 
const std::string & graffiti_at (const tripoint &p) const
 
void set_graffiti (const tripoint &p, const std::string &contents)
 
void delete_graffiti (const tripoint &p)
 
int climb_difficulty (const tripoint &p) const
 Checks 3x3 block centered on p for terrain to climb. More...
 
bool has_floor (const tripoint &p) const
 
bool supports_above (const tripoint &p) const
 Does this tile support vehicles and furniture above it. More...
 
bool has_floor_or_support (const tripoint &p) const
 
void drop_everything (const tripoint &p)
 Handles map objects of given type (not creatures) falling down. More...
 
void drop_furniture (const tripoint &p)
 
void drop_items (const tripoint &p)
 
void drop_vehicle (const tripoint &p)
 
void drop_fields (const tripoint &p)
 
void process_falling ()
 Invoked drop_everything on cached dirty tiles. More...
 
bool is_cornerfloor (const tripoint &p) const
 
void generate (const tripoint &p, const time_point &when)
 
void place_spawns (const mongroup_id &group, int chance, const point &p1, const point &p2, float density, bool individual=false, bool friendly=false, const std::string &name="NONE", int mission_id=-1)
 
void place_gas_pump (const point &p, int charges, const std::string &fuel_type)
 
void place_gas_pump (const point &p, int charges)
 
void place_toilet (const point &p, int charges=6 *4)
 
void place_vending (const point &p, const item_group_id &type, bool reinforced=false)
 
character_id place_npc (const point &p, const string_id< npc_template > &type, bool force=false)
 
void apply_faction_ownership (const point &p1, const point &p2, const faction_id &id)
 
void add_spawn (const mtype_id &type, int count, const tripoint &p, bool friendly=false, int faction_id=-1, int mission_id=-1, const std::string &name="NONE") const
 
void do_vehicle_caching (int z)
 
void build_map_cache (int zlev, bool skip_lightmap=false)
 
void build_obstacle_cache (const tripoint &start, const tripoint &end, float(&obstacle_cache)[MAPSIZE_X][MAPSIZE_Y])
 
vehicleadd_vehicle (const vgroup_id &type, const tripoint &p, units::angle dir, int init_veh_fuel=-1, int init_veh_status=-1, bool merge_wrecks=true)
 
vehicleadd_vehicle (const vgroup_id &type, const point &p, units::angle dir, int init_veh_fuel=-1, int init_veh_status=-1, bool merge_wrecks=true)
 
vehicleadd_vehicle (const vproto_id &type, const tripoint &p, units::angle dir, int init_veh_fuel=-1, int init_veh_status=-1, bool merge_wrecks=true)
 
vehicleadd_vehicle (const vproto_id &type, const point &p, units::angle dir, int init_veh_fuel=-1, int init_veh_status=-1, bool merge_wrecks=true)
 
float light_transparency (const tripoint &p) const
 
lit_level light_at (const tripoint &p) const
 
float ambient_light_at (const tripoint &p) const
 
bool is_transparent (const tripoint &p) const
 Returns whether the tile at p is transparent(you can look past it). More...
 
bool pl_sees (const tripoint &t, int max_range) const
 Whether the player character (g->u) can see the given square (local map coordinates). More...
 
bool pl_line_of_sight (const tripoint &t, int max_range) const
 Uses the map cache to tell if the player could see the given square. More...
 
tripoint get_abs_sub () const
 return abs_sub More...
 
tripoint getabs (const tripoint &p) const
 Translates local (to this map) coordinates of a square to global absolute coordinates. More...
 
point getabs (const point &p) const
 
tripoint getlocal (const tripoint &p) const
 Inverse of getabs. More...
 
point getlocal (const point &p) const
 
virtual bool inbounds (const tripoint &p) const
 
bool inbounds (const point &p) const
 
bool inbounds_z (const int z) const
 
void clip_to_bounds (tripoint &p) const
 Clips the coordinates of p to fit the map bounds. More...
 
void clip_to_bounds (int &x, int &y) const
 
void clip_to_bounds (int &x, int &y, int &z) const
 
int getmapsize () const
 
bool has_zlevels () const
 
void rotate (int turns, bool setpos_safe=false)
 Rotates this map, and all of its contents, by the specified multiple of 90 degrees. More...
 
void spawn_monsters (bool ignore_sight)
 Spawn monsters from submap spawn points and from the overmap. More...
 
void rotten_item_spawn (const item &item, const tripoint &p)
 Checks to see if the item that is rotting away generates a creature when it does. More...
 
void build_outside_cache (int zlev)
 
bool build_floor_cache (int zlev)
 
void build_floor_caches ()
 
void update_suspension_cache (const int &z)
 
bash_results bash_items (const tripoint &p, const bash_params &params)
 
bash_results bash_field (const tripoint &p, const bash_params &params)
 
bash_results bash_ter_success (const tripoint &p, const bash_params &params)
 
bash_results bash_furn_success (const tripoint &p, const bash_params &params)
 
void process_items ()
 
const level_cacheget_cache_ref (int zlev) const
 
const pathfinding_cacheget_pathfinding_cache_ref (int zlev) const
 
void update_pathfinding_cache (int zlev) const
 
void update_visibility_cache (int zlev)
 
const visibility_variablesget_visibility_variables_cache () const
 
void update_submap_active_item_status (const tripoint &p)
 
const std::set< tripoint > & get_submaps_with_active_items () const
 
tripoint_range< tripointpoints_in_rectangle (const tripoint &from, const tripoint &to) const
 
tripoint_range< tripointpoints_in_radius (const tripoint &center, size_t radius, size_t radiusz=0) const
 
tripoint_range< tripointpoints_on_zlevel () const
 Yields a range of all points that are contained in the map and have the z-level of this map (abs_sub). More...
 
tripoint_range< tripointpoints_on_zlevel (int z) const
 Same as above, but uses the specific z-level. More...
 
std::list< item_locationget_active_items_in_radius (const tripoint &center, int radius) const
 
std::list< item_locationget_active_items_in_radius (const tripoint &center, int radius, special_item_type type) const
 
std::list< tripointfind_furnitures_with_flag_in_radius (const tripoint &center, size_t radius, const std::string &flag, size_t radiusz=0)
 returns positions of furnitures with matching flag in the specified radius More...
 
std::list< tripointfind_furnitures_or_vparts_with_flag_in_radius (const tripoint &center, size_t radius, const std::string &flag, size_t radiusz=0)
 returns positions of furnitures or vehicle parts with matching flag in the specified radius More...
 
std::list< Creature * > get_creatures_in_radius (const tripoint &center, size_t radius, size_t radiusz=0)
 returns creatures in specified radius More...
 
level_cacheaccess_cache (int zlev)
 
const level_cacheaccess_cache (int zlev) const
 
bool dont_draw_lower_floor (const tripoint &p)
 
void support_dirty (const tripoint &p)
 
void spawn_monsters_submap (const tripoint &gp, bool ignore_sight)
 
void spawn_monsters_submap_group (const tripoint &gp, mongroup &group, bool ignore_sight)
 
fieldget_field (const tripoint &p)
 
submapgetsubmap (size_t grididx) const
 Get the submap pointer with given index in grid, the index must be valid! More...
 
submapget_submap_at (const tripoint &p) const
 Get the submap pointer containing the specified position within the reality bubble. More...
 
submapget_submap_at (const point &p) const
 
submapget_submap_at (const tripoint &p, point &offset_p) const
 Get the submap pointer containing the specified position within the reality bubble. More...
 
submapget_submap_at (const point &p, point &offset_p) const
 
submapget_submap_at_grid (const point &gridp) const
 Get submap pointer in the grid at given grid coordinates. More...
 
submapget_submap_at_grid (const tripoint &gridp) const
 
int calc_max_populated_zlev ()
 Caclulate the greatest populated zlevel in the loaded submaps and save in the level cache. More...
 
void invalidate_max_populated_zlev (int zlev)
 Conditionally invalidates max_pupulated_zlev cache if the submap uniformity change occurs above current max_pupulated_zlev value. More...
 
int move_cost_internal (const furn_t &furniture, const ter_t &terrain, const vehicle *veh, int vpart) const
 Internal versions of public functions to avoid checking same variables multiple times. More...
 
int bash_rating_internal (int str, const furn_t &furniture, const ter_t &terrain, bool allow_floor, const vehicle *veh, int part) const
 
bool draw_maptile (const catacurses::window &w, const tripoint &p, const maptile &tile, const drawsq_params &params) const
 Internal version of the drawsq. More...
 
void draw_from_above (const catacurses::window &w, const tripoint &p, const maptile &tile, const drawsq_params &params) const
 Draws the tile as seen from above. More...
 
int determine_wall_corner (const tripoint &p) const
 
void apply_light_source (const tripoint &p, float luminance)
 
void add_light_source (const tripoint &p, float luminance)
 
void apply_directional_light (const tripoint &p, int direction, float luminance)
 
void apply_light_arc (const tripoint &p, units::angle, float luminance, units::angle wideangle=30_degrees)
 
void apply_light_ray (bool lit[MAPSIZE_X][MAPSIZE_Y], const tripoint &s, const tripoint &e, float luminance)
 
void add_light_from_items (const tripoint &p, item_stack::iterator begin, item_stack::iterator end)
 
std::unique_ptr< vehicleadd_vehicle_to_map (std::unique_ptr< vehicle > veh, bool merge_wrecks)
 Takes a vehicle already created with new and attempts to place it on the map, checking for collisions. More...
 
ter_id get_roof (const tripoint &p, bool allow_air) const
 
void process_items_in_submap (submap &current_submap, const tripoint &gridp)
 
void process_items_in_vehicles (submap &current_submap)
 
void process_items_in_vehicle (vehicle &cur_veh, submap &current_submap)
 
template<typename Functor >
void function_over (const tripoint &start, const tripoint &end, Functor fun) const
 Runs a functor over given submaps over submaps in the area, getting next submap only when the current one "runs out" rather than every time. More...
 
level_cacheget_cache (int zlev) const
 
pathfinding_cacheget_pathfinding_cache (int zlev) const
 
void saven (const tripoint &grid)
 
void loadn (const tripoint &grid, bool update_vehicles)
 
void loadn (const point &grid, bool update_vehicles)
 
void actualize (const tripoint &grid)
 Fast forward a submap that has just been loading into this map. More...
 
void add_roofs (const tripoint &grid)
 Hacks in missing roofs. More...
 
template<typename Container >
void remove_rotten_items (Container &items, const tripoint &p)
 Go through the list of items, update their rotten status and remove items that have rotten away completely. More...
 
void fill_funnels (const tripoint &p, const time_point &since)
 Try to fill funnel based items here. More...
 
void grow_plant (const tripoint &p)
 Try to grow a harvestable plant to the next stage(s). More...
 
void restock_fruits (const tripoint &p, const time_duration &time_since_last_actualize)
 Try to grow fruits on static plants (not planted by the player) More...
 
void produce_sap (const tripoint &p, const time_duration &time_since_last_actualize)
 Produce sap on tapped maple trees. More...
 
void rad_scorch (const tripoint &p, const time_duration &time_since_last_actualize)
 Radiation-related plant (and fungus?) death. More...
 
void decay_cosmetic_fields (const tripoint &p, const time_duration &time_since_last_actualize)
 
void player_in_field (player &u)
 
void monster_in_field (monster &z)
 
void shift_traps (const tripoint &shift)
 As part of the map shifting, this shifts the trap locations stored in traplocs. More...
 
void copy_grid (const tripoint &to, const tripoint &from)
 
void draw_map (mapgendata &dat)
 
void draw_office_tower (mapgendata &dat)
 
void draw_lab (mapgendata &dat)
 
void draw_temple (mapgendata &dat)
 
void draw_mine (mapgendata &dat)
 
void draw_anthill (mapgendata &dat)
 
void draw_slimepit (mapgendata &dat)
 
void draw_triffid (mapgendata &dat)
 
void draw_connections (mapgendata &dat)
 
bool build_transparency_cache (int zlev)
 
bool build_vision_transparency_cache (const Character &player)
 
void build_sunlight_cache (int pzlev)
 
void generate_lightmap (int zlev)
 
void build_seen_cache (const tripoint &origin, int target_z)
 Calculates the Field Of View for the provided map from the given x, y coordinates. More...
 
void apply_character_light (Character &p)
 
void apply_vision_transparency_cache (const tripoint &center, int target_z, float(&vision_restore_cache)[9], bool(&blocked_restore_cache)[8])
 
void restore_vision_transparency_cache (const tripoint &center, int target_z, float(&vision_restore_cache)[9], bool(&blocked_restore_cache)[8])
 
void set_abs_sub (const tripoint &p)
 Sets abs_sub, see there. More...
 
size_t get_nonant (const tripoint &gridp) const
 Get the index of a submap pointer in the grid given by grid coordinates. More...
 
size_t get_nonant (const point &gridp) const
 
void setsubmap (size_t grididx, submap *smap)
 Set the submap pointer in grid at the give index. More...
 

Detailed Description

Manage and cache data about a part of the map.

Despite the name, this class isn't actually responsible for managing the map as a whole. For that function, see mapbuffer. Instead, this class loads a part of the mapbuffer into a cache, and adds certain temporary information such as lighting calculations to it.

To understand the following descriptions better, you should also read Map Management

The map coordinates always start at (0, 0) for the top-left and end at (map_width-1, map_height-1) for the bottom-right.

The actual map data is stored in submap instances. These instances are managed by mapbuffer. References to the currently active submaps are stored in map::grid: 0 1 2 3 4 5 6 7 8 In this example, the top-right submap would be at grid[2].

When the player moves between submaps, the whole map is shifted, so that if the player moves one submap to the right, (0, 0) now points to a tile one submap to the right from before

Definition at line 383 of file map.h.

Member Enumeration Documentation

◆ iteration_state

enum map::iteration_state
private

Enum used by functors in function_over to control execution.

Enumerator
ITER_CONTINUE 
ITER_SKIP_SUBMAP 
ITER_SKIP_ZLEVEL 
ITER_FINISH 

Definition at line 1976 of file map.h.

1976 {
1977 ITER_CONTINUE = 0, // Keep iterating
1978 ITER_SKIP_SUBMAP, // Skip the rest of this submap
1979 ITER_SKIP_ZLEVEL, // Skip the rest of this z-level
1980 ITER_FINISH // End iteration
1981 };
@ ITER_SKIP_ZLEVEL
Definition: map.h:1979
@ ITER_SKIP_SUBMAP
Definition: map.h:1978
@ ITER_CONTINUE
Definition: map.h:1977
@ ITER_FINISH
Definition: map.h:1980

Constructor & Destructor Documentation

◆ map() [1/2]

map::map ( int  mapsize = MAPSIZE,
bool  zlev = false 
)

Definition at line 174 of file map.cpp.

175{
176 my_MAPSIZE = mapsize;
177 zlevels = zlev;
178 if( zlevels ) {
179 grid.resize( static_cast<size_t>( my_MAPSIZE * my_MAPSIZE * OVERMAP_LAYERS ), nullptr );
180 } else {
181 grid.resize( static_cast<size_t>( my_MAPSIZE * my_MAPSIZE ), nullptr );
182 }
183
184 for( auto &ptr : caches ) {
185 ptr = std::make_unique<level_cache>();
186 }
187
188 for( auto &ptr : pathfinding_caches ) {
189 ptr = std::make_unique<pathfinding_cache>();
190 }
191
192 dbg( DL::Info ) << "map::map(): my_MAPSIZE: " << my_MAPSIZE << " z-levels enabled:" << zlevels;
193 traplocs.resize( trap::count() );
194}
std::vector< std::vector< tripoint > > traplocs
This vector contains an entry for each trap type, it has therefor the same size as the traplist vecto...
Definition: map.h:2008
std::array< std::unique_ptr< pathfinding_cache >, OVERMAP_LAYERS > pathfinding_caches
Definition: map.h:2018
std::vector< submap * > grid
The list of currently loaded submaps.
Definition: map.h:2001
int my_MAPSIZE
Definition: map.h:1829
bool zlevels
Definition: map.h:1830
std::array< std::unique_ptr< level_cache >, OVERMAP_LAYERS > caches
Holds caches for visibility, light, transparency and vehicles.
Definition: map.h:2016
@ Info
Information (default: enabled).
const void * ptr(const T *p)
\rst Converts p to const void* for pointer formatting.
static constexpr int OVERMAP_LAYERS
#define dbg(x)
Definition: map.cpp:138
static size_t count()
Definition: trap.cpp:95

References caches, trap::count(), dbg, grid, Info, my_MAPSIZE, OVERMAP_LAYERS, pathfinding_caches, ptr(), traplocs, and zlevels.

Referenced by check_submap_active_item_consistency().

◆ map() [2/2]

map::map ( bool  zlev)
inlineexplicit

Definition at line 391 of file map.h.

391: map( MAPSIZE, zlev ) { }
map(int mapsize=MAPSIZE, bool zlev=false)
Definition: map.cpp:174
static constexpr int MAPSIZE

◆ ~map()

map::~map ( )
virtualdefault

Member Function Documentation

◆ access_cache() [1/2]

level_cache & map::access_cache ( int  zlev)

Definition at line 8745 of file map.cpp.

8746{
8747 if( zlev >= -OVERMAP_DEPTH && zlev <= OVERMAP_HEIGHT ) {
8748 return *caches[zlev + OVERMAP_DEPTH];
8749 }
8750
8751 debugmsg( "access_cache called with invalid z-level: %d", zlev );
8752 return nullcache;
8753}
#define debugmsg(...)
Debug message of level DL::Error and class DC::DebugMsg, also includes the source file name and line,...
Definition: debug.h:74
static constexpr int OVERMAP_HEIGHT
static constexpr int OVERMAP_DEPTH
static level_cache nullcache
Definition: map.cpp:142

References caches, debugmsg, nullcache, OVERMAP_DEPTH, and OVERMAP_HEIGHT.

Referenced by get_known_connections(), game::place_player_overmap(), process_items(), explosion_handler::shrapnel(), scent_map::update(), and game::vertical_shift().

◆ access_cache() [2/2]

const level_cache & map::access_cache ( int  zlev) const

Definition at line 8755 of file map.cpp.

8756{
8757 if( zlev >= -OVERMAP_DEPTH && zlev <= OVERMAP_HEIGHT ) {
8758 return *caches[zlev + OVERMAP_DEPTH];
8759 }
8760
8761 debugmsg( "access_cache called with invalid z-level: %d", zlev );
8762 return nullcache;
8763}

References caches, debugmsg, nullcache, OVERMAP_DEPTH, and OVERMAP_HEIGHT.

◆ accessible_items()

bool map::accessible_items ( const tripoint t) const

Check whether the player can access the items located .

Certain furniture/terrain may prevent that (e.g. a locked safe).

Definition at line 6568 of file map.cpp.

6569{
6570 return !has_flag( "SEALED", t ) || has_flag( "LIQUIDCONT", t );
6571}
bool has_flag(const std::string &flag, const tripoint &p) const
Definition: map.cpp:2293

References has_flag().

Referenced by basecamp::form_crafting_inventory(), inventory::form_from_map(), player::get_eligible_containers_for_crafting(), has_clear_path_to_pickup_items(), try_fuel_fire(), and use_charges().

◆ actualize()

void map::actualize ( const tripoint grid)
protected

Fast forward a submap that has just been loading into this map.

This is used to rot and remove rotten items, grow plants, fill funnels etc.

Definition at line 7419 of file map.cpp.

7420{
7421 submap *const tmpsub = get_submap_at_grid( grid );
7422 if( tmpsub == nullptr ) {
7423 debugmsg( "Actualize called on null submap (%d,%d,%d)", grid.x, grid.y, grid.z );
7424 return;
7425 }
7426
7427 const time_duration time_since_last_actualize = calendar::turn - tmpsub->last_touched;
7428 const bool do_funnels = ( grid.z >= 0 );
7429
7430 // check spoiled stuff, and fill up funnels while we're at it
7431 for( int x = 0; x < SEEX; x++ ) {
7432 for( int y = 0; y < SEEY; y++ ) {
7433 const tripoint pnt = sm_to_ms_copy( grid ) + point( x, y );
7434 const point p( x, y );
7435 const auto &furn = this->furn( pnt ).obj();
7436 if( furn.has_flag( "EMITTER" ) ) {
7437 field_furn_locs.push_back( pnt );
7438 }
7439 // plants contain a seed item which must not be removed under any circumstances
7440 if( !furn.has_flag( "DONT_REMOVE_ROTTEN" ) ) {
7441 remove_rotten_items( tmpsub->get_items( { x, y } ), pnt );
7442 }
7443
7444 const auto trap_here = tmpsub->get_trap( p );
7445 if( trap_here != tr_null ) {
7446 traplocs[trap_here.to_i()].push_back( pnt );
7447 }
7448 const ter_t &ter = tmpsub->get_ter( p ).obj();
7449 if( ter.trap != tr_null && ter.trap != tr_ledge ) {
7450 traplocs[ter.trap.to_i()].push_back( pnt );
7451 }
7452
7453 if( do_funnels ) {
7454 fill_funnels( pnt, tmpsub->last_touched );
7455 }
7456
7457 grow_plant( pnt );
7458
7459 restock_fruits( pnt, time_since_last_actualize );
7460
7461 produce_sap( pnt, time_since_last_actualize );
7462
7463 rad_scorch( pnt, time_since_last_actualize );
7464
7465 decay_cosmetic_fields( pnt, time_since_last_actualize );
7466 }
7467 }
7468
7469 // the last time we touched the submap, is right now.
7470 tmpsub->last_touched = calendar::turn;
7471}
const T & obj() const
Definition: ammo_effect.cpp:26
int to_i() const
Returns the identifier as plain int.
Definition: int_id.h:84
void remove_rotten_items(Container &items, const tripoint &p)
Go through the list of items, update their rotten status and remove items that have rotten away compl...
Definition: map.cpp:7102
void rad_scorch(const tripoint &p, const time_duration &time_since_last_actualize)
Radiation-related plant (and fungus?) death.
Definition: map.cpp:7353
void fill_funnels(const tripoint &p, const time_point &since)
Try to fill funnel based items here.
Definition: map.cpp:7141
std::vector< tripoint > field_furn_locs
Vector of tripoints containing active field-emitting furniture.
Definition: map.h:2012
void decay_cosmetic_fields(const tripoint &p, const time_duration &time_since_last_actualize)
Definition: map.cpp:7399
void restock_fruits(const tripoint &p, const time_duration &time_since_last_actualize)
Try to grow fruits on static plants (not planted by the player)
Definition: map.cpp:7242
ter_id ter(const tripoint &p) const
Definition: map.cpp:1498
void grow_plant(const tripoint &p)
Try to grow a harvestable plant to the next stage(s).
Definition: map.cpp:7164
submap * get_submap_at_grid(const point &gridp) const
Get submap pointer in the grid at given grid coordinates.
Definition: map.h:1879
void produce_sap(const tripoint &p, const time_duration &time_since_last_actualize)
Produce sap on tapped maple trees.
Definition: map.cpp:7256
furn_id furn(const tripoint &p) const
Definition: map.cpp:1348
Definition: submap.h:65
time_point last_touched
Definition: submap.h:240
trap_id get_trap(const point &p) const
Definition: submap.h:73
ter_id get_ter(const point &p) const
Definition: submap.h:99
cata::colony< item > & get_items(const point &p)
Definition: submap.h:161
A duration defined as a number of specific time units.
Definition: calendar.h:180
point sm_to_ms_copy(const point &p)
static constexpr int SEEX
static constexpr int SEEY
static const trap_str_id tr_ledge("tr_ledge")
time_point turn
Definition: calendar.cpp:36
Definition: point.h:35
Definition: mapdata.h:457
trap_id tr_null
Definition: trap.cpp:276

References debugmsg, decay_cosmetic_fields(), field_furn_locs, fill_funnels(), furn(), submap::get_items(), get_submap_at_grid(), submap::get_ter(), submap::get_trap(), grid, grow_plant(), submap::last_touched, int_id< T >::obj(), produce_sap(), rad_scorch(), remove_rotten_items(), restock_fruits(), SEEX, SEEY, sm_to_ms_copy(), ter(), int_id< T >::to_i(), tr_ledge, tr_null, traplocs, and calendar::turn.

Referenced by loadn().

◆ add_camp()

void map::add_camp ( const tripoint_abs_omt omt_pos,
const std::string &  name 
)

Definition at line 5591 of file map.cpp.

5592{
5593 basecamp temp_camp = basecamp( name, omt_pos );
5594 overmap_buffer.add_camp( temp_camp );
5595 g->u.camps.insert( omt_pos );
5596 g->validate_camps();
5597}
std::string name(const tripoint &p)
Definition: map.cpp:1325
void add_camp(const basecamp &camp)
Add Basecamp to overmapbuffer.
std::unique_ptr< game > g
Definition: game.cpp:276
overmapbuffer overmap_buffer

References overmapbuffer::add_camp(), g, name(), and overmap_buffer.

Referenced by get_basecamp().

◆ add_computer()

computer * map::add_computer ( const tripoint p,
const std::string &  name,
int  security 
)

Definition at line 5790 of file mapgen.cpp.

5791{
5792 // TODO: Turn this off?
5793 ter_set( p, t_console );
5794 point l;
5795 submap *const place_on_submap = get_submap_at( p, l );
5796 place_on_submap->set_computer( l, computer( name, security ) );
5797 return place_on_submap->get_computer( l );
5798}
bool ter_set(const tripoint &p, const ter_id &new_terrain)
Definition: map.cpp:1639
submap * get_submap_at(const tripoint &p) const
Get the submap pointer containing the specified position within the reality bubble.
Definition: map.cpp:8314
void set_computer(const point &p, const computer &c)
Definition: submap.cpp:203
const computer * get_computer(const point &p) const
Definition: submap.cpp:177
ter_id t_console
Definition: mapdata.cpp:704

References submap::get_computer(), get_submap_at(), name(), submap::set_computer(), t_console, and ter_set().

Referenced by jmapgen_computer::apply(), create_lab_consoles(), draw_lab(), mission_start::place_npc_software(), and science_room().

◆ add_corpse()

void map::add_corpse ( const tripoint p)

Definition at line 8458 of file map.cpp.

8459{
8460 item body;
8461
8462 const bool isReviveSpecial = one_in( 10 );
8463
8464 if( !isReviveSpecial ) {
8465 body = item::make_corpse();
8466 } else {
8467 body = item::make_corpse( mon_zombie );
8468 body.set_flag( "REVIVE_SPECIAL" );
8469 }
8470
8471 put_items_from_loc( item_group_id( "default_zombie_clothes" ), p );
8472 if( one_in( 3 ) ) {
8473 put_items_from_loc( item_group_id( "default_zombie_items" ), p );
8474 }
8475
8476 add_item_or_charges( p, body );
8477}
Definition: item.h:177
static item make_corpse(const mtype_id &mt=string_id< mtype >::NULL_ID(), time_point turn=calendar::turn, const std::string &name="", int upgrade_time=-1)
Make a corpse of the given monster type.
Definition: item.cpp:507
item & set_flag(const std::string &flag)
Idempotent filter setting an item specific flag.
Definition: item.cpp:5251
item & add_item_or_charges(const tripoint &pos, item obj, bool overflow=true)
Adds an item to map tile or stacks charges.
Definition: map.cpp:4235
std::vector< item * > put_items_from_loc(const item_group_id &loc, const tripoint &p, const time_point &turn=calendar::start_of_cataclysm)
Place items from an item group at p.
Definition: mapgen.cpp:5578
static const mtype_id mon_zombie("mon_zombie")
bool one_in(int chance)
Definition: rng.cpp:65
string_id< Item_group > item_group_id
Definition: type_id.h:77

References add_item_or_charges(), item::make_corpse(), mon_zombie, one_in(), put_items_from_loc(), and item::set_flag().

Referenced by add_corpse(), MapExtras::mx_looters(), MapExtras::mx_mayhem(), and MapExtras::mx_minefield().

◆ add_field()

bool map::add_field ( const tripoint p,
const field_type_id type_id,
int  intensity = INT_MAX,
const time_duration age = 0_turns,
bool  hit_player = true 
)

Add field entry at point, or set intensity if present.

Returns
false if the field could not be created (out of bounds), otherwise true.

Definition at line 5408 of file map.cpp.

5410{
5411 if( !inbounds( p ) ) {
5412 return false;
5413 }
5414
5415 if( !type_id ) {
5416 debugmsg( "Tried to add null field" );
5417 return false;
5418 }
5419
5420 const field_type &fd_type = *type_id;
5421 intensity = std::min( intensity, fd_type.get_max_intensity() );
5422 if( intensity <= 0 ) {
5423 return false;
5424 }
5425
5426 point l;
5427 submap *const current_submap = get_submap_at( p, l );
5428 current_submap->is_uniform = false;
5430
5431 if( current_submap->get_field( l ).add_field( type_id, intensity, age ) ) {
5432 //Only adding it to the count if it doesn't exist.
5433 if( !current_submap->field_count++ ) {
5434 get_cache( p.z ).field_cache.set( static_cast<size_t>( p.x / SEEX + ( (
5435 p.y / SEEX ) * MAPSIZE ) ) );
5436 }
5437 }
5438
5439 if( hit_player ) {
5440 Character &player_character = get_player_character();
5441 if( g != nullptr && this == &get_map() && p == player_character.pos() ) {
5442 //Hit the player with the field if it spawned on top of them.
5443 creature_in_field( player_character );
5444 }
5445 }
5446
5447 // Dirty the transparency cache now that field processing doesn't always do it
5448 if( fd_type.dirty_transparency_cache || !fd_type.is_transparent() ) {
5451 }
5452
5453 if( fd_type.is_dangerous() ) {
5455 }
5456
5457 // Ensure blood type fields don't hang in the air
5458 if( zlevels && fd_type.accelerated_decay ) {
5459 support_dirty( p );
5460 }
5461
5462 return true;
5463}
Character & get_player_character()
Definition: character.cpp:387
const tripoint & pos() const override
Definition: character.cpp:714
bool add_field(const field_type_id &field_type_to_add, int new_intensity=1, const time_duration &new_age=0_turns)
Inserts the given field_type_id into the field list for a given tile if it does not already exist.
Definition: field.cpp:190
void set_transparency_cache_dirty(const int zlev)
Sets a dirty flag on the a given cache.
Definition: map.h:405
level_cache & get_cache(int zlev) const
Definition: map.h:2036
virtual bool inbounds(const tripoint &p) const
Definition: map.cpp:7769
void set_pathfinding_cache_dirty(int zlev)
Definition: map.cpp:8800
void creature_in_field(Creature &critter)
Apply field effects to the creature when it's on a square with fields.
Definition: map_field.cpp:1563
void support_dirty(const tripoint &p)
Definition: map.cpp:2267
void invalidate_max_populated_zlev(int zlev)
Conditionally invalidates max_pupulated_zlev cache if the submap uniformity change occurs above curre...
Definition: map.cpp:8993
void set_seen_cache_dirty(const tripoint change_location)
Definition: map.h:421
int field_count
Definition: submap.h:239
field & get_field(const point &p)
Definition: submap.h:170
bool is_uniform
Definition: submap.h:233
map & get_map()
Definition: map.cpp:146
bool accelerated_decay
Definition: field_type.h:179
bool is_transparent() const
Definition: field_type.h:262
bool dirty_transparency_cache
Definition: field_type.h:161
bool is_dangerous() const
Definition: field_type.h:256
int get_max_intensity() const
Definition: field_type.h:268
std::bitset< MAPSIZE *MAPSIZE > field_cache
Definition: map.h:352
int y
Definition: point.h:151
int z
Definition: point.h:152
int x
Definition: point.h:150

References field_type::accelerated_decay, field::add_field(), creature_in_field(), debugmsg, field_type::dirty_transparency_cache, level_cache::field_cache, submap::field_count, g, get_cache(), submap::get_field(), get_map(), field_type::get_max_intensity(), get_player_character(), get_submap_at(), inbounds(), invalidate_max_populated_zlev(), field_type::is_dangerous(), field_type::is_transparent(), submap::is_uniform, MAPSIZE, Character::pos(), SEEX, set_pathfinding_cache_dirty(), set_seen_cache_dirty(), set_transparency_cache_dirty(), support_dirty(), tripoint::x, tripoint::y, tripoint::z, and zlevels.

Referenced by Character::activate_bionic(), jmapgen_field::apply(), apply_ammo_effects(), Character::blossoms(), mattack::boomer(), mattack::boomer_glow(), start_location::burn(), create_anomaly(), spell::create_field(), create_hot_air(), explosion_handler::do_blast(), draw_lab(), draw_mine(), draw_temple(), draw_triffid(), drop_fields(), editmap::edit_fld(), iexamine::fireplace(), mattack::flame(), gas_spread_to(), hit_with_fire(), madd_field(), MapExtras::mx_casings(), MapExtras::mx_corpses(), MapExtras::mx_drugdeal(), MapExtras::mx_looters(), MapExtras::mx_mayhem(), MapExtras::mx_minefield(), MapExtras::mx_portal_in(), MapExtras::mx_roadblock(), MapExtras::mx_spider(), game::process_artifact(), process_fields_in_submap(), item::process_litcig(), explosion_handler::explosion_funcs::resonance_cascade(), mattack::riotbot(), set_field_intensity(), shoot(), Character::suffer_from_other_mutations(), explosion_iuse::trigger_explosion(), and consume_drug_iuse::use().

◆ add_item() [1/2]

void map::add_item ( const point p,
item  new_item 
)
inline

Definition at line 1306 of file map.h.

1306 {
1307 add_item( tripoint( p, abs_sub.z ), new_item );
1308 }
tripoint abs_sub
Absolute coordinates of first submap (get_submap_at(0,0)) This is in submap coordinates (see overmapb...
Definition: map.h:1844
item & add_item(const tripoint &p, item new_item)
Place an item on the map, despite the parameter name, this is not necessarily a new item.
Definition: map.cpp:4335

References abs_sub, add_item(), and tripoint::z.

◆ add_item() [2/2]

item & map::add_item ( const tripoint p,
item  new_item 
)

Place an item on the map, despite the parameter name, this is not necessarily a new item.

WARNING: does -not- check volume or stack charges. player functions (drop etc) should use map::add_item_or_charges

Returns
The item that got added, or nulitem.

Definition at line 4335 of file map.cpp.

4336{
4337 if( !inbounds( p ) ) {
4338 return null_item_reference();
4339 }
4340 point l;
4341 submap *const current_submap = get_submap_at( p, l );
4342
4343 // Process foods when they are added to the map, here instead of add_item_at()
4344 // to avoid double processing food and corpses during active item processing.
4345 if( new_item.is_food() ) {
4346 new_item.process( nullptr, p, false );
4347 }
4348
4349 if( new_item.made_of( LIQUID ) && has_flag( "SWIMMABLE", p ) ) {
4350 return null_item_reference();
4351 }
4352
4353 if( has_flag( "DESTROY_ITEM", p ) ) {
4354 return null_item_reference();
4355 }
4356
4357 if( new_item.has_flag( "ACT_IN_FIRE" ) && get_field( p, fd_fire ) != nullptr ) {
4358 if( new_item.has_flag( "BOMB" ) && new_item.is_transformable() ) {
4359 //Convert a bomb item into its transformable version, e.g. incendiary grenade -> active incendiary grenade
4360 new_item.convert( dynamic_cast<const iuse_transform *>
4361 ( new_item.type->get_use( "transform" )->get_actor_ptr() )->target );
4362 }
4363 new_item.active = true;
4364 }
4365
4366 if( new_item.is_map() && !new_item.has_var( "reveal_map_center_omt" ) ) {
4367 new_item.set_var( "reveal_map_center_omt", ms_to_omt_copy( getabs( p ) ) );
4368 }
4369
4370 current_submap->is_uniform = false;
4372
4373 current_submap->update_lum_add( l, new_item );
4374
4375 const map_stack::iterator new_pos = current_submap->get_items( l ).insert( new_item );
4376 if( new_item.needs_processing() ) {
4377 if( current_submap->active_items.empty() ) {
4378 submaps_with_active_items.insert( tripoint( abs_sub.x + p.x / SEEX, abs_sub.y + p.y / SEEY, p.z ) );
4379 }
4380 current_submap->active_items.add( *new_pos, l );
4381 }
4382
4383 return *new_pos;
4384}
void add(item &it, point location)
Adds the reference to the cache.
bool empty() const
Returns true if the cache is empty.
bool is_transformable() const
Definition: item.cpp:6838
bool needs_processing() const
Whether the item should be processed (by calling process).
Definition: item.cpp:8803
bool active
Definition: item.h:2234
bool process(player *carrier, const tripoint &pos, bool activate, float insulation=1, temperature_flag flag=temperature_flag::TEMP_NORMAL)
This is called once each turn.
Definition: item.cpp:9464
const std::vector< material_id > & made_of() const
The ids of all the materials this is made of.
Definition: item.cpp:6293
item & convert(const itype_id &new_type)
Filter converting this instance to another type preserving all other aspects.
Definition: item.cpp:533
bool has_var(const std::string &name) const
Whether the variable is defined at all.
Definition: item.cpp:1070
void set_var(const std::string &name, int value)
Definition: item.cpp:995
bool has_flag(const std::string &flag) const
Definition: item.cpp:5222
bool is_map() const
Definition: item.cpp:6594
bool is_food() const
Definition: item.cpp:6472
const itype * type
Definition: item.h:2157
Transform an item into a specific type.
Definition: iuse_actor.h:52
itype_id target
type of the resulting item
Definition: iuse_actor.h:58
std::set< tripoint > submaps_with_active_items
Set of submaps that contain active items in absolute coordinates.
Definition: map.h:2022
field_entry * get_field(const tripoint &p, const field_type_id &type)
Get field of specific type at point.
Definition: map.cpp:5385
tripoint getabs(const tripoint &p) const
Translates local (to this map) coordinates of a square to global absolute coordinates.
Definition: map.cpp:8273
void update_lum_add(const point &p, const item &i)
Definition: submap.h:130
active_item_cache active_items
Definition: submap.h:237
point ms_to_omt_copy(const point &p)
@ LIQUID
Definition: enums.h:175
field_type_id fd_fire
Definition: field_type.cpp:345
item & null_item_reference()
Returns a reference to a null item (see item::is_null).
Definition: item.cpp:322
const use_function * get_use(const std::string &iuse_name) const
Definition: itype.cpp:91
iuse_actor * get_actor_ptr()
Definition: iuse.h:314

References abs_sub, item::active, submap::active_items, active_item_cache::add(), item::convert(), active_item_cache::empty(), fd_fire, use_function::get_actor_ptr(), get_field(), submap::get_items(), get_submap_at(), itype::get_use(), getabs(), item::has_flag(), has_flag(), item::has_var(), inbounds(), invalidate_max_populated_zlev(), item::is_food(), item::is_map(), item::is_transformable(), submap::is_uniform, LIQUID, item::made_of(), ms_to_omt_copy(), item::needs_processing(), null_item_reference(), item::process(), SEEX, SEEY, item::set_var(), submaps_with_active_items, iuse_transform::target, item::type, submap::update_lum_add(), tripoint::x, tripoint::y, and tripoint::z.

Referenced by add_item(), add_item_or_charges(), item::ammo_consume(), iexamine::arcfurnace_empty(), iexamine::arcfurnace_full(), draw_mine(), extract_or_wreck_cbms(), iexamine::fvat_empty(), iexamine::fvat_full(), iexamine::keg(), iexamine::kiln_empty(), iexamine::kiln_full(), mill_activate(), mill_load_food(), Character::perform_uninstall(), place_gas_pump(), place_toilet(), iexamine::pour_into_keg(), iexamine::reload_furniture(), smoker_activate(), smoker_load_food(), Character::uninstall_bionic(), and avatar_action::wield().

◆ add_item_or_charges() [1/2]

item & map::add_item_or_charges ( const point p,
item  obj,
bool  overflow = true 
)
inline

Definition at line 1294 of file map.h.

1294 {
1295 return add_item_or_charges( tripoint( p, abs_sub.z ), obj, overflow );
1296 }

References abs_sub, add_item_or_charges(), and tripoint::z.

◆ add_item_or_charges() [2/2]

item & map::add_item_or_charges ( const tripoint pos,
item  obj,
bool  overflow = true 
)

Adds an item to map tile or stacks charges.

Parameters
posWhere to add item
objItem to add
overflowif destination is full attempt to drop on adjacent tiles
Returns
reference to dropped (and possibly stacked) item or null item on failure
Warning
function is relatively expensive and meant for user initiated actions, not mapgen

Definition at line 4235 of file map.cpp.

4236{
4237 // Checks if item would not be destroyed if added to this tile
4238 auto valid_tile = [&]( const tripoint & e ) {
4239 if( !inbounds( e ) ) {
4240 // should never happen
4241 debugmsg( "add_item_or_charges: %s is out of bounds (adding item '%s' [%d])",
4242 e.to_string(), obj.typeId().c_str(), obj.charges );
4243 return false;
4244 }
4245
4246 // Some tiles destroy items (e.g. lava)
4247 if( has_flag( "DESTROY_ITEM", e ) ) {
4248 return false;
4249 }
4250
4251 // Cannot drop liquids into tiles that are comprised of liquid
4252 if( obj.made_of( LIQUID ) && has_flag( "SWIMMABLE", e ) ) {
4253 return false;
4254 }
4255
4256 return true;
4257 };
4258
4259 // Checks if sufficient space at tile to add item
4260 auto valid_limits = [&]( const tripoint & e ) {
4261 return obj.volume() <= free_volume( e ) && i_at( e ).size() < MAX_ITEM_IN_SQUARE;
4262 };
4263
4264 // Performs the actual insertion of the object onto the map
4265 auto place_item = [&]( const tripoint & tile ) -> item& {
4266 if( obj.count_by_charges() )
4267 {
4268 for( auto &e : i_at( tile ) ) {
4269 if( e.merge_charges( obj ) ) {
4270 return e;
4271 }
4272 }
4273 }
4274
4275 support_dirty( tile );
4276 return add_item( tile, obj );
4277 };
4278
4279 // Some items never exist on map as a discrete item (must be contained by another item)
4280 if( obj.has_flag( "NO_DROP" ) ) {
4281 return null_item_reference();
4282 }
4283
4284 // If intended drop tile destroys the item then we don't attempt to overflow
4285 if( !valid_tile( pos ) ) {
4286 return null_item_reference();
4287 }
4288
4289 if( ( !has_flag( "NOITEM", pos ) || ( has_flag( "LIQUIDCONT", pos ) && obj.made_of( LIQUID ) ) )
4290 && valid_limits( pos ) ) {
4291 // Pass map into on_drop, because this map may not be the global map object (in mapgen, for instance).
4292 if( obj.made_of( LIQUID ) || !obj.has_flag( "DROP_ACTION_ONLY_IF_LIQUID" ) ) {
4293 if( obj.on_drop( pos, *this ) ) {
4294 return null_item_reference();
4295 }
4296
4297 }
4298 // If tile can contain items place here...
4299 return place_item( pos );
4300
4301 } else if( overflow ) {
4302 // ...otherwise try to overflow to adjacent tiles (if permitted)
4303 const int max_dist = 2;
4304 std::vector<tripoint> tiles = closest_points_first( pos, max_dist );
4305 tiles.erase( tiles.begin() ); // we already tried this position
4306 const int max_path_length = 4 * max_dist;
4307 const pathfinding_settings setting( 0, max_dist, max_path_length, 0, false, true, false, false,
4308 false );
4309 for( const tripoint &e : tiles ) {
4310 if( !inbounds( e ) ) {
4311 continue;
4312 }
4313 //must be a path to the target tile
4314 if( route( pos, e, setting ).empty() ) {
4315 continue;
4316 }
4317 if( obj.made_of( LIQUID ) || !obj.has_flag( "DROP_ACTION_ONLY_IF_LIQUID" ) ) {
4318 if( obj.on_drop( e, *this ) ) {
4319 return null_item_reference();
4320 }
4321 }
4322
4323 if( !valid_tile( e ) || !valid_limits( e ) ||
4324 has_flag( "NOITEM", e ) || has_flag( "SEALED", e ) ) {
4325 continue;
4326 }
4327 return place_item( e );
4328 }
4329 }
4330
4331 // failed due to lack of space at target tile (+/- overflow tiles)
4332 return null_item_reference();
4333}
size_t size() const
Definition: item_stack.cpp:10
bool count_by_charges() const
Definition: item.cpp:5885
units::volume volume(bool integral=false) const
Total volume of an item accounting for all contained/integrated items NOTE: Result is rounded up to n...
Definition: item.cpp:5021
int charges
Definition: item.h:2196
bool on_drop(const tripoint &pos)
Invokes item type's itype::drop_action.
Definition: item.cpp:9854
const itype_id & typeId() const
return the unique identifier of the items underlying type
Definition: item.cpp:8227
map_stack i_at(const tripoint &p)
Definition: map.cpp:4090
units::volume free_volume(const tripoint &p)
Definition: map.cpp:4230
std::vector< tripoint > route(const tripoint &f, const tripoint &t, const pathfinding_settings &settings, const std::set< tripoint > &pre_closed={{ }}) const
Calculate the best path using A*.
const char * c_str() const
Interface to the plain C-string of the id.
Definition: string_id.h:247
std::vector< coords::coord_point< Point, Origin, Scale > > closest_points_first(const coords::coord_point< Point, Origin, Scale > &loc, int min_dist, int max_dist)
Definition: coordinates.h:596
static constexpr int MAX_ITEM_IN_SQUARE

References add_item(), string_id< T >::c_str(), item::charges, closest_points_first(), item::count_by_charges(), debugmsg, free_volume(), item::has_flag(), has_flag(), i_at(), inbounds(), LIQUID, item::made_of(), MAX_ITEM_IN_SQUARE, null_item_reference(), item::on_drop(), wrapped_vehicle::pos, route(), item_stack::size(), support_dirty(), item::typeId(), and item::volume().

Referenced by Character::absorb_hit(), computer_session::action_conveyor(), computer_session::action_data_anal(), computer_session::action_sample(), Character::activate_bionic(), add_corpse(), add_item_or_charges(), MapgenRemovePartHandler::add_item_or_charges(), jmapgen_liquid_item::apply(), butchery_drops_harvest(), butchery_quarter(), defense_game::caravan(), game::catch_a_monster(), activity_handlers::chop_logs_finish(), doors::close_door(), talk_function::companion_return(), complete_construction(), cycle_action(), monexamine::deactivate_pet(), iexamine::deployed_furniture(), game::disable_robot(), basecamp::distribute_food(), draw_lab(), Character::drop_invalid_inventory(), drop_items(), npc::drop_items(), drop_on_map(), drop_or_embed_projectile(), talk_function::drop_stolen_item(), talk_function::drop_weapon(), monexamine::dump_items(), iexamine::elevator(), explosion_handler::emp_blast(), farm_action(), fetch_activity(), talk_function::field_plant(), activity_handlers::fill_liquid_do_turn(), iexamine::fireplace(), game::forced_door_closing(), fromPumpFuel(), iexamine::fvat_full(), iexamine::gaspump(), handle_harvest(), pickup::handle_spillable_contents(), iexamine::harvest_plant(), Character::i_add_or_drop(), map_stack::insert(), make_mon_corpse(), make_rubble(), mill_activate(), move_item(), MapExtras::mx_grave(), MapExtras::mx_mayhem(), MapExtras::mx_minefield(), iexamine::nanofab(), om_set_hide_site(), liquid_handler::perform_liquid_transfer(), iexamine::pit_covered(), Character::place_corpse(), basecamp::place_results(), activity_handlers::plant_seed_finish(), talk_function::player_weapon_drop(), iexamine::portable_structure(), process_fields_in_submap(), item::process_litcig(), put_into_vehicle(), iexamine::quern_examine(), rcdrive(), monexamine::remove_armor(), monexamine::remove_bag_from(), monexamine::remove_battery(), rod_fish(), scatter_chunks(), set_item_map(), activity_handlers::shear_finish(), smash_items(), smoker_activate(), iexamine::smoker_options(), spawn_an_item(), spawn_artifact(), spawn_items(), spawn_natural_artifact(), item::spill_contents(), item_contents::spill_contents(), mdeath::splatter(), stash_on_pet(), iexamine::toPumpFuel(), iexamine::trap(), iexamine::tree_maple(), iexamine::tree_maple_tapped(), unroll_digging(), and unpack_actor::use().

◆ add_light_from_items()

void map::add_light_from_items ( const tripoint p,
item_stack::iterator  begin,
item_stack::iterator  end 
)
private

Definition at line 64 of file lightmap.cpp.

66{
67 for( auto itm_it = begin; itm_it != end; ++itm_it ) {
68 float ilum = 0.0f; // brightness
69 units::angle iwidth = 0_degrees; // 0-360 degrees. 0 is a circular light_source
70 units::angle idir = 0_degrees; // otherwise, it's a light_arc pointed in this direction
71 if( itm_it->getlight( ilum, iwidth, idir ) ) {
72 if( iwidth > 0_degrees ) {
73 apply_light_arc( p, idir, ilum, iwidth );
74 } else {
75 add_light_source( p, ilum );
76 }
77 }
78 }
79}
void apply_light_arc(const tripoint &p, units::angle, float luminance, units::angle wideangle=30_degrees)
Definition: lightmap.cpp:1664
void add_light_source(const tripoint &p, float luminance)
Definition: lightmap.cpp:613

References add_light_source(), and apply_light_arc().

Referenced by generate_lightmap().

◆ add_light_source()

void map::add_light_source ( const tripoint p,
float  luminance 
)
private

Definition at line 613 of file lightmap.cpp.

614{
615 auto &light_source_buffer = get_cache( p.z ).light_source_buffer;
616 light_source_buffer[p.x][p.y] = std::max( luminance, light_source_buffer[p.x][p.y] );
617}
float light_source_buffer[MAPSIZE_X][MAPSIZE_Y]
Definition: map.h:318

References get_cache(), level_cache::light_source_buffer, tripoint::x, tripoint::y, and tripoint::z.

Referenced by add_light_from_items(), and generate_lightmap().

◆ add_roofs()

void map::add_roofs ( const tripoint grid)
protected

Hacks in missing roofs.

Should be removed when 3D mapgen is done.

Definition at line 7473 of file map.cpp.

7474{
7475 if( !zlevels ) {
7476 // No roofs required!
7477 // Why not? Because submaps below and above don't exist yet
7478 return;
7479 }
7480
7481 submap *const sub_here = get_submap_at_grid( grid );
7482 if( sub_here == nullptr ) {
7483 debugmsg( "Tried to add roofs/floors on null submap on %d,%d,%d",
7484 grid.x, grid.y, grid.z );
7485 return;
7486 }
7487
7488 bool check_roof = grid.z > -OVERMAP_DEPTH;
7489
7490 submap *const sub_below = check_roof ? get_submap_at_grid( grid + tripoint_below ) : nullptr;
7491
7492 if( check_roof && sub_below == nullptr ) {
7493 debugmsg( "Tried to add roofs to sm at %d,%d,%d, but sm below doesn't exist",
7494 grid.x, grid.y, grid.z );
7495 return;
7496 }
7497
7498 for( int x = 0; x < SEEX; x++ ) {
7499 for( int y = 0; y < SEEY; y++ ) {
7500 const ter_id ter_here = sub_here->get_ter( { x, y } );
7501 if( ter_here != t_open_air ) {
7502 continue;
7503 }
7504
7505 if( !check_roof ) {
7506 // Make sure we don't have open air at lowest z-level
7507 sub_here->set_ter( { x, y }, t_rock_floor );
7508 continue;
7509 }
7510
7511 const ter_t &ter_below = sub_below->get_ter( { x, y } ).obj();
7512 if( ter_below.roof ) {
7513 // TODO: Make roof variable a ter_id to speed this up
7514 sub_here->set_ter( { x, y }, ter_below.roof.id() );
7515 }
7516 }
7517 }
7518}
int_id< T > id() const
Translate the string based it to the matching integer based id.
Definition: ammo_effect.cpp:54
void set_ter(const point &p, ter_id terr)
Definition: submap.h:103
ter_id t_open_air
Definition: mapdata.cpp:727
ter_id t_rock_floor
Definition: mapdata.cpp:627
static constexpr tripoint tripoint_below
Definition: point.h:295
ter_str_id roof
Definition: mapdata.h:467

References debugmsg, get_submap_at_grid(), submap::get_ter(), grid, string_id< T >::id(), OVERMAP_DEPTH, ter_t::roof, SEEX, SEEY, submap::set_ter(), t_open_air, t_rock_floor, tripoint_below, and zlevels.

Referenced by loadn(), and shift().

◆ add_spawn()

void map::add_spawn ( const mtype_id type,
int  count,
const tripoint p,
bool  friendly = false,
int  faction_id = -1,
int  mission_id = -1,
const std::string &  name = "NONE" 
) const

Definition at line 5585 of file mapgen.cpp.

5587{
5588 if( p.x < 0 || p.x >= SEEX * my_MAPSIZE || p.y < 0 || p.y >= SEEY * my_MAPSIZE ) {
5589 debugmsg( "Bad add_spawn(%s, %d, %d, %d)", type.c_str(), count, p.x, p.y );
5590 return;
5591 }
5592 point offset;
5593 submap *place_on_submap = get_submap_at( p, offset );
5594
5595 if( !place_on_submap ) {
5596 debugmsg( "centadodecamonant doesn't exist in grid; within add_spawn(%s, %d, %d, %d, %d)",
5597 type.c_str(), count, p.x, p.y, p.z );
5598 return;
5599 }
5601 return;
5602 }
5603 spawn_point tmp( type, count, offset, faction_id, mission_id, friendly, name );
5604 place_on_submap->spawns.push_back( tmp );
5605}
static bool monster_is_blacklisted(const mtype_id &m)
Definition: mongroup.cpp:280
std::vector< spawn_point > spawns
Definition: submap.h:241
@ type
Definition: enums.h:75
constexpr size_t count()
Definition: fmtlib_core.h:1073

References detail::count(), debugmsg, friendly, get_submap_at(), MonsterGroupManager::monster_is_blacklisted(), my_MAPSIZE, name(), SEEX, SEEY, submap::spawns, type, tripoint::x, tripoint::y, and tripoint::z.

Referenced by jmapgen_monster::apply(), generate(), mission_start::kill_horde_master(), mapgen_ants_generic(), mapgen_ants_larvae(), mapgen_ants_queen(), mapgen_hive(), mapgen_road(), MapExtras::mx_collegekids(), MapExtras::mx_drugdeal(), MapExtras::mx_helicopter(), MapExtras::mx_house_spider(), MapExtras::mx_house_wasp(), MapExtras::mx_jabberwock(), MapExtras::mx_marloss_pilgrimage(), MapExtras::mx_military(), MapExtras::mx_roadblock(), MapExtras::mx_science(), MapExtras::mx_shia(), MapExtras::mx_spider(), mission_start::place_dog(), place_spawns(), mission_start::place_zombie_mom(), process_fields_in_submap(), and rotten_item_spawn().

◆ add_splash()

void map::add_splash ( const field_type_id type,
const tripoint center,
int  radius,
int  intensity 
)

Definition at line 5540 of file map.cpp.

5542{
5543 if( !type.id() ) {
5544 return;
5545 }
5546 // TODO: use Bresenham here and take obstacles into account
5547 for( const tripoint &pnt : points_in_radius( center, radius ) ) {
5548 if( trig_dist( pnt, center ) <= radius && !one_in( intensity ) ) {
5549 add_splatter( type, pnt );
5550 }
5551 }
5552}
tripoint_range< tripoint > points_in_radius(const tripoint &center, size_t radius, size_t radiusz=0) const
Definition: map.cpp:8617
void add_splatter(const field_type_id &type, const tripoint &where, int intensity=1)
Definition: map.cpp:5491
int trig_dist(const coords::coord_point< Point, Origin, Scale > &loc1, const coords::coord_point< Point, Origin, Scale > &loc2)
Definition: coordinates.h:512

References add_splatter(), center, one_in(), points_in_radius(), trig_dist(), and type.

Referenced by smash_items().

◆ add_splatter()

void map::add_splatter ( const field_type_id type,
const tripoint where,
int  intensity = 1 
)

Definition at line 5491 of file map.cpp.

5492{
5493 if( !type.id() || intensity <= 0 ) {
5494 return;
5495 }
5496 if( type.obj().is_splattering ) {
5497 if( const optional_vpart_position vp = veh_at( where ) ) {
5498 vehicle *const veh = &vp->vehicle();
5499 // Might be -1 if all the vehicle's parts at where are marked for removal
5500 const int part = veh->part_displayed_at( vp->mount() );
5501 if( part != -1 ) {
5502 veh->part( part ).blood += 200 * std::min( intensity, 3 ) / 3;
5503 return;
5504 }
5505 }
5506 }
5507 mod_field_intensity( where, type, intensity );
5508}
optional_vpart_position veh_at(const tripoint &p) const
Checks if tile is occupied by vehicle and by which part.
Definition: map.cpp:1009
int mod_field_intensity(const tripoint &p, const field_type_id &type, int offset)
Increment/decrement intensity of field entry at point, creating if not present, removing if intensity...
Definition: map.cpp:5334
Simple wrapper to forward functions that may return a cata::optional to vpart_position.
A vehicle as a whole with all its components.
Definition: vehicle.h:675
vehicle(const vproto_id &type_id, int init_veh_fuel=-1, int init_veh_status=-1)
Definition: vehicle.cpp:251
vehicle_part & part(int part_num)
Definition: vehicle.cpp:7080
int part_displayed_at(const point &dp) const
Returns which part (as an index into the parts list) is the one that will be displayed for the given ...
Definition: vehicle.cpp:2970
int blood
how much blood covers part (in turns).
Definition: vehicle.h:398

References vehicle_part::blood, mod_field_intensity(), vehicle::part(), vehicle::part_displayed_at(), type, veh_at(), and vehicle::vehicle().

Referenced by add_splash(), add_splatter_trail(), Creature::bleed(), activity_handlers::butcher_finish(), scatter_chunks(), and mdeath::splatter().

◆ add_splatter_trail()

void map::add_splatter_trail ( const field_type_id type,
const tripoint from,
const tripoint to 
)

Definition at line 5510 of file map.cpp.

5512{
5513 if( !type.id() ) {
5514 return;
5515 }
5516 auto trail = line_to( from, to );
5517 int remainder = trail.size();
5518 tripoint last_point = from;
5519 for( tripoint &elem : trail ) {
5520 add_splatter( type, elem );
5521 remainder--;
5522 if( obstructed_by_vehicle_rotation( last_point, elem ) ) {
5523 if( one_in( 2 ) ) {
5524 elem.x = last_point.x;
5525 add_splatter( type, elem, remainder );
5526 } else {
5527 elem.y = last_point.y;
5528 add_splatter( type, elem, remainder );
5529 }
5530 return;
5531 }
5532 if( impassable( elem ) ) { // Blood splatters stop at walls.
5533 add_splatter( type, elem, remainder );
5534 return;
5535 }
5536 last_point = elem;
5537 }
5538}
bool obstructed_by_vehicle_rotation(const tripoint &from, const tripoint &to) const
Checks if a rotated vehicle is blocking diagonal movement, tripoints must be adjacent.
Definition: map.cpp:6495
bool impassable(const tripoint &p) const
Definition: map.cpp:1795
std::vector< coords::coord_point< Point, Origin, Scale > > line_to(const coords::coord_point< Point, Origin, Scale > &loc1, const coords::coord_point< Point, Origin, Scale > &loc2)
Definition: coordinates.h:548

References add_splatter(), impassable(), line_to(), obstructed_by_vehicle_rotation(), one_in(), type, tripoint::x, and tripoint::y.

Referenced by activity_handlers::butcher_finish(), MapExtras::mx_casings(), MapExtras::mx_mayhem(), MapExtras::mx_minefield(), projectile_attack(), and activity_handlers::pulp_do_turn().

◆ add_vehicle() [1/4]

vehicle * map::add_vehicle ( const vgroup_id type,
const point p,
units::angle  dir,
int  init_veh_fuel = -1,
int  init_veh_status = -1,
bool  merge_wrecks = true 
)

Definition at line 5613 of file mapgen.cpp.

5615{
5616 return add_vehicle( type.obj().pick(), p, dir, veh_fuel, veh_status, merge_wrecks );
5617}
vehicle * add_vehicle(const vgroup_id &type, const tripoint &p, units::angle dir, int init_veh_fuel=-1, int init_veh_status=-1, bool merge_wrecks=true)
Definition: mapgen.cpp:5607

References add_vehicle(), and type.

◆ add_vehicle() [2/4]

◆ add_vehicle() [3/4]

vehicle * map::add_vehicle ( const vproto_id type,
const point p,
units::angle  dir,
int  init_veh_fuel = -1,
int  init_veh_status = -1,
bool  merge_wrecks = true 
)

Definition at line 5619 of file mapgen.cpp.

5621{
5622 return add_vehicle( type, tripoint( p, abs_sub.z ), dir, veh_fuel, veh_status, merge_wrecks );
5623}

References abs_sub, add_vehicle(), type, and tripoint::z.

◆ add_vehicle() [4/4]

vehicle * map::add_vehicle ( const vproto_id type,
const tripoint p,
units::angle  dir,
int  init_veh_fuel = -1,
int  init_veh_status = -1,
bool  merge_wrecks = true 
)

Definition at line 5625 of file mapgen.cpp.

5627{
5628 if( !type.is_valid() ) {
5629 debugmsg( "Nonexistent vehicle type: \"%s\"", type.c_str() );
5630 return nullptr;
5631 }
5632 if( !inbounds( p ) ) {
5633 dbg( DL::Warn ) << string_format( "Out of bounds add_vehicle t=%s d=%d p=%s",
5634 type, to_degrees( dir ), p.to_string() );
5635 return nullptr;
5636 }
5637
5638 // debugmsg("n=%d x=%d y=%d MAPSIZE=%d ^2=%d", nonant, x, y, MAPSIZE, MAPSIZE*MAPSIZE);
5639 auto veh = std::make_unique<vehicle>( type, veh_fuel, veh_status );
5640 tripoint p_ms = p;
5641 veh->sm_pos = ms_to_sm_remain( p_ms );
5642 veh->pos = p_ms.xy();
5643 veh->place_spawn_items();
5644 // for backwards compatibility, we always spawn with a pivot point of (0,0) so
5645 // that the mount at (0,0) is located at the spawn position.
5646 veh->set_facing_and_pivot( dir, point_zero, false );
5647 //debugmsg("adding veh: %d, sm: %d,%d,%d, pos: %d, %d", veh, veh->smx, veh->smy, veh->smz, veh->posx, veh->posy);
5648 std::unique_ptr<vehicle> placed_vehicle_up =
5649 add_vehicle_to_map( std::move( veh ), merge_wrecks );
5650 vehicle *placed_vehicle = placed_vehicle_up.get();
5651
5652 if( placed_vehicle != nullptr ) {
5653 submap *place_on_submap = get_submap_at_grid( placed_vehicle->sm_pos );
5654 place_on_submap->vehicles.push_back( std::move( placed_vehicle_up ) );
5655 place_on_submap->is_uniform = false;
5657
5658 auto &ch = get_cache( placed_vehicle->sm_pos.z );
5659 ch.vehicle_list.insert( placed_vehicle );
5660 add_vehicle_to_cache( placed_vehicle );
5661
5662 //debugmsg ("grid[%d]->vehicles.size=%d veh.parts.size=%d", nonant, grid[nonant]->vehicles.size(),veh.parts.size());
5663 }
5664 return placed_vehicle;
5665}
std::unique_ptr< vehicle > add_vehicle_to_map(std::unique_ptr< vehicle > veh, bool merge_wrecks)
Takes a vehicle already created with new and attempts to place it on the map, checking for collisions...
Definition: mapgen.cpp:5676
void add_vehicle_to_cache(vehicle *)
Definition: map.cpp:271
std::vector< std::unique_ptr< vehicle > > vehicles
Vehicles on this submap (their (0,0) point is on this submap).
Definition: submap.h:247
tripoint sm_pos
Submap coordinates of the currently loaded submap (see game::m) that contains this vehicle.
Definition: vehicle.h:1901
point ms_to_sm_remain(int &x, int &y)
@ Warn
Warning (default: enabled).
#define dbg(x)
Definition: mapgen.cpp:99
bool move(avatar &you, map &m, const tripoint &d)
constexpr double to_degrees(const units::angle v)
Definition: units_angle.h:36
static constexpr point point_zero
Definition: point.h:274
std::string string_format(std::string format, Args &&...args)
Simple wrapper over string_formatter::parse.
constexpr point xy() const
Definition: point.h:220
std::string to_string() const
Definition: point.cpp:16

References add_vehicle_to_cache(), add_vehicle_to_map(), dbg, debugmsg, get_cache(), get_submap_at_grid(), inbounds(), invalidate_max_populated_zlev(), submap::is_uniform, avatar_action::move(), ms_to_sm_remain(), point_zero, vehicle::sm_pos, string_format(), units::to_degrees(), tripoint::to_string(), type, submap::vehicles, Warn, tripoint::xy(), and tripoint::z.

◆ add_vehicle_to_cache()

void map::add_vehicle_to_cache ( vehicle veh)

Definition at line 271 of file map.cpp.

272{
273 if( veh == nullptr ) {
274 debugmsg( "Tried to add null vehicle to cache" );
275 return;
276 }
277
278 // Get parts
279 for( const vpart_reference &vpr : veh->get_all_parts() ) {
280 if( vpr.part().removed ) {
281 continue;
282 }
283 const tripoint p = veh->global_part_pos3( vpr.part() );
284 level_cache &ch = get_cache( p.z );
285 ch.veh_in_active_range = true;
286 ch.veh_cached_parts[p] = std::make_pair( veh, static_cast<int>( vpr.part_index() ) );
287 if( inbounds( p ) ) {
288 ch.veh_exists_at[p.x][p.y] = true;
289 }
290 }
291
293}
bool last_full_vehicle_list_dirty
Definition: map.h:2033
vehicle_part_range get_all_parts() const
Yields a range containing all parts (including broken ones) that can be iterated over.
Definition: vehicle.cpp:7070
tripoint global_part_pos3(const int &index) const
Get the coordinates of the studied part of the vehicle.
Definition: vehicle.cpp:3286
This is a wrapper over a vehicle pointer and a reference to a part of it.
bool veh_in_active_range
Definition: map.h:354
bool veh_exists_at[MAPSIZE_X][MAPSIZE_Y]
Definition: map.h:355
std::map< tripoint, std::pair< vehicle *, int > > veh_cached_parts
Definition: map.h:356

References debugmsg, vehicle::get_all_parts(), get_cache(), vehicle::global_part_pos3(), inbounds(), last_full_vehicle_list_dirty, level_cache::veh_cached_parts, level_cache::veh_exists_at, level_cache::veh_in_active_range, tripoint::x, tripoint::y, and tripoint::z.

Referenced by add_vehicle(), veh_interact::complete_vehicle(), displace_vehicle(), construct::done_vehicle(), loadn(), vehicle::part_removal_cleanup(), and reset_vehicle_cache().

◆ add_vehicle_to_map()

std::unique_ptr< vehicle > map::add_vehicle_to_map ( std::unique_ptr< vehicle veh,
bool  merge_wrecks 
)
private

Takes a vehicle already created with new and attempts to place it on the map, checking for collisions.

If the vehicle can't be placed, returns NULL, otherwise returns a pointer to the placed vehicle, which may not necessarily be the one passed in (if wreckage is created by fusing cars).

Parameters
vehThe vehicle to place on the map.
merge_wrecksWhether crashed vehicles become part of each other
Returns
The vehicle that was finally placed.

Definition at line 5676 of file mapgen.cpp.

5678{
5679 //We only want to check once per square, so loop over all structural parts
5680 std::vector<int> frame_indices = veh->all_parts_at_location( "structure" );
5681
5682 //Check for boat type vehicles that should be placeable in deep water
5683 const bool can_float = size( veh->get_avail_parts( "FLOATS" ) ) > 2;
5684
5685 //When hitting a wall, only smash the vehicle once (but walls many times)
5686 bool needs_smashing = false;
5687
5688 veh->attach();
5689 veh->refresh_position();
5690
5691 for( std::vector<int>::const_iterator part = frame_indices.begin();
5692 part != frame_indices.end(); part++ ) {
5693 const auto p = veh->global_part_pos3( *part );
5694
5695 //Don't spawn anything in water
5696 if( has_flag_ter( TFLAG_DEEP_WATER, p ) && !can_float ) {
5697 return nullptr;
5698 }
5699
5700 // Don't spawn shopping carts on top of another vehicle or other obstacle.
5701 if( veh->type == vproto_id( "shopping_cart" ) ) {
5702 if( veh_at( p ) || impassable( p ) ) {
5703 return nullptr;
5704 }
5705 }
5706
5707 //For other vehicles, simulate collisions with (non-shopping cart) stuff
5708 vehicle *const other_veh = veh_pointer_or_null( veh_at( p ) );
5709 if( other_veh != nullptr && other_veh->type != vproto_id( "shopping_cart" ) ) {
5710 if( !merge_wrecks ) {
5711 return nullptr;
5712 }
5713
5714 // Hard wreck-merging limit: 200 tiles
5715 // Merging is slow for big vehicles which lags the mapgen
5716 if( frame_indices.size() + other_veh->all_parts_at_location( "structure" ).size() > 200 ) {
5717 return nullptr;
5718 }
5719
5720 /* There's a vehicle here, so let's fuse them together into wreckage and
5721 * smash them up. It'll look like a nasty collision has occurred.
5722 * Trying to do a local->global->local conversion would be a major
5723 * headache, so instead, let's make another vehicle whose (0, 0) point
5724 * is the (0, 0) of the existing vehicle, convert the coordinates of both
5725 * vehicles into global coordinates, find the distance between them and
5726 * p and then install them that way.
5727 * Create a vehicle with type "null" so it starts out empty. */
5728 auto wreckage = std::make_unique<vehicle>();
5729 wreckage->pos = other_veh->pos;
5730 wreckage->sm_pos = other_veh->sm_pos;
5731
5732 //Where are we on the global scale?
5733 const tripoint global_pos = wreckage->global_pos3();
5734
5735 for( const vpart_reference &vpr : veh->get_all_parts() ) {
5736 const tripoint part_pos = veh->global_part_pos3( vpr.part() ) - global_pos;
5737 // TODO: change mount points to be tripoint
5738 wreckage->install_part( part_pos.xy(), vpr.part() );
5739 }
5740
5741 for( const vpart_reference &vpr : other_veh->get_all_parts() ) {
5742 const tripoint part_pos = other_veh->global_part_pos3( vpr.part() ) - global_pos;
5743 wreckage->install_part( part_pos.xy(), vpr.part() );
5744
5745 }
5746
5747 wreckage->name = _( "Wreckage" );
5748
5749 // Now get rid of the old vehicles
5750 std::unique_ptr<vehicle> old_veh = detach_vehicle( other_veh );
5751 // Failure has happened here when caches are corrupted due to bugs.
5752 // Add an assertion to avoid null-pointer dereference later.
5753 assert( old_veh );
5754
5755 // Try again with the wreckage
5756 std::unique_ptr<vehicle> new_veh = add_vehicle_to_map( std::move( wreckage ), true );
5757 if( new_veh != nullptr ) {
5758 new_veh->smash( *this );
5759 return new_veh;
5760 }
5761
5762 // If adding the wreck failed, we want to restore the vehicle we tried to merge with
5763 add_vehicle_to_map( std::move( old_veh ), false );
5764 return nullptr;
5765
5766 } else if( impassable( p ) ) {
5767 if( !merge_wrecks ) {
5768 return nullptr;
5769 }
5770
5771 // There's a wall or other obstacle here; destroy it
5772 destroy( p, true );
5773
5774 // Some weird terrain, don't place the vehicle
5775 if( impassable( p ) ) {
5776 return nullptr;
5777 }
5778
5779 needs_smashing = true;
5780 }
5781 }
5782
5783 if( needs_smashing ) {
5784 veh->smash( *this );
5785 }
5786
5787 return veh;
5788}
void destroy(const tripoint &p, bool silent=false)
Keeps bashing a square until it can't be bashed anymore.
Definition: map.cpp:3638
std::unique_ptr< vehicle > detach_vehicle(vehicle *veh)
Definition: map.cpp:354
bool has_flag_ter(const std::string &flag, const tripoint &p) const
Definition: map.cpp:2312
point pos
Position of the vehicle inside the submap that contains the vehicle.
Definition: vehicle.h:1916
vproto_id type
Type of the vehicle as it was spawned.
Definition: vehicle.h:1855
std::vector< int > all_parts_at_location(const std::string &location) const
Returns all parts in the vehicle that exist in the given location slot.
Definition: vehicle.cpp:2781
@ TFLAG_DEEP_WATER
Definition: mapdata.h:301
const size_t size
Definition: om_direction.h:27
#define _(msg)
Definition: translations.h:116
vehicle * veh_pointer_or_null(const optional_vpart_position &p)

References _, add_vehicle_to_map(), vehicle::all_parts_at_location(), destroy(), detach_vehicle(), vehicle::get_all_parts(), vehicle::global_part_pos3(), has_flag_ter(), impassable(), avatar_action::move(), vehicle::pos, om_direction::size, vehicle::sm_pos, TFLAG_DEEP_WATER, vehicle::type, veh_at(), veh_pointer_or_null(), and tripoint::xy().

Referenced by add_vehicle(), and add_vehicle_to_map().

◆ adjust_radiation() [1/2]

void map::adjust_radiation ( const point p,
const int  delta 
)
inline

Definition at line 1222 of file map.h.

1222 {
1223 adjust_radiation( tripoint( p, abs_sub.z ), delta );
1224 }
void adjust_radiation(const tripoint &p, int delta)
Increment the radiation in the given tile by the given delta (decrement it if delta is negative)
Definition: map.cpp:4058

References abs_sub, adjust_radiation(), and tripoint::z.

◆ adjust_radiation() [2/2]

void map::adjust_radiation ( const tripoint p,
int  delta 
)

Increment the radiation in the given tile by the given delta (decrement it if delta is negative)

Definition at line 4058 of file map.cpp.

4059{
4060 if( !inbounds( p ) ) {
4061 return;
4062 }
4063
4064 point l;
4065 submap *const current_submap = get_submap_at( p, l );
4066
4067 int current_radiation = current_submap->get_radiation( l );
4068 current_submap->set_radiation( l, current_radiation + delta );
4069}
void set_radiation(const point &p, const int radiation)
Definition: submap.h:116
int get_radiation(const point &p) const
Definition: submap.h:112

References submap::get_radiation(), get_submap_at(), inbounds(), and submap::set_radiation().

Referenced by computer_session::action_irradiator(), adjust_radiation(), MapExtras::mx_crater(), MapExtras::mx_portal_in(), process_fields_in_submap(), and Character::suffer_from_radiation().

◆ ambient_light_at()

float map::ambient_light_at ( const tripoint p) const

Definition at line 646 of file lightmap.cpp.

647{
648 if( !inbounds( p ) ) {
649 return 0.0f;
650 }
651
652 return get_cache_ref( p.z ).lm[p.x][p.y].max();
653}
const level_cache & get_cache_ref(int zlev) const
Definition: map.h:2049
float max() const
Definition: shadowcasting.h:45
four_quadrants lm[MAPSIZE_X][MAPSIZE_Y]
Definition: map.h:314

References get_cache_ref(), inbounds(), level_cache::lm, four_quadrants::max(), tripoint::x, tripoint::y, and tripoint::z.

Referenced by apply_character_light(), game::print_terrain_info(), and Creature::sees().

◆ apparent_light_at()

lit_level map::apparent_light_at ( const tripoint p,
const visibility_variables cache 
) const

Determine the visible light level for a tile, based on light_at for the tile, vision distance, etc.

Parameters
pThe tile on this map to draw.
cacheCurrently cached visibility parameters

Definition at line 729 of file lightmap.cpp.

730{
731 const int dist = rl_dist( g->u.pos(), p );
732
733 // Clairvoyance overrides everything.
734 if( dist <= cache.u_clairvoyance ) {
735 return lit_level::BRIGHT;
736 }
737 const auto &map_cache = get_cache_ref( p.z );
738 const apparent_light_info a = apparent_light_helper( map_cache, p );
739
740 // Unimpaired range is an override to strictly limit vision range based on various conditions,
741 // but the player can still see light sources.
742 if( dist > g->u.unimpaired_range() ) {
743 if( !a.obstructed && map_cache.sm[p.x][p.y] > 0.0 ) {
745 } else {
746 return lit_level::DARK;
747 }
748 }
749 if( a.obstructed ) {
750 if( a.apparent_light > LIGHT_AMBIENT_LIT ) {
751 if( a.apparent_light > cache.g_light_level ) {
752 // This represents too hazy to see detail,
753 // but enough light getting through to illuminate.
755 } else {
756 // If it's not brighter than the surroundings, it just ends up shadowy.
757 return lit_level::LOW;
758 }
759 } else {
760 return lit_level::BLANK;
761 }
762 }
763 // Then we just search for the light level in descending order.
764 if( a.apparent_light > LIGHT_SOURCE_BRIGHT || map_cache.sm[p.x][p.y] > 0.0 ) {
765 return lit_level::BRIGHT;
766 }
767 if( a.apparent_light > LIGHT_AMBIENT_LIT ) {
768 return lit_level::LIT;
769 }
770 if( a.apparent_light >= cache.vision_threshold ) {
771 return lit_level::LOW;
772 } else {
773 return lit_level::BLANK;
774 }
775}
static apparent_light_info apparent_light_helper(const level_cache &map_cache, const tripoint &p)
Helper function for light claculation; exposed here for map editor.
Definition: lightmap.cpp:667
int rl_dist(const coords::coord_point< Point, Origin, Scale > &loc1, const coords::coord_point< Point, Origin, Scale > &loc2)
Definition: coordinates.h:519
static constexpr float LIGHT_SOURCE_BRIGHT
Definition: lightmap.h:9
static constexpr float LIGHT_AMBIENT_LIT
Definition: lightmap.h:18
constexpr double a
Definition: magic.cpp:1030
float vision_threshold
Definition: map.h:128
int u_clairvoyance
Definition: map.h:127

References a, apparent_light_helper(), BLANK, BRIGHT, BRIGHT_ONLY, DARK, g, visibility_variables::g_light_level, get_cache_ref(), LIGHT_AMBIENT_LIT, LIGHT_SOURCE_BRIGHT, LIT, LOW, rl_dist(), visibility_variables::u_clairvoyance, visibility_variables::vision_threshold, tripoint::x, tripoint::y, and tripoint::z.

Referenced by game::draw_look_around_cursor(), game::print_all_tile_info(), editmap::update_view_with_help(), and update_visibility_cache().

◆ apparent_light_helper()

map::apparent_light_info map::apparent_light_helper ( const level_cache map_cache,
const tripoint p 
)
static

Helper function for light claculation; exposed here for map editor.

Definition at line 667 of file lightmap.cpp.

669{
670 const float vis = std::max( map_cache.seen_cache[p.x][p.y], map_cache.camera_cache[p.x][p.y] );
671 const bool obstructed = vis <= LIGHT_TRANSPARENCY_SOLID + 0.1;
672
673 auto is_opaque = [&map_cache]( const point & p ) {
674 return map_cache.transparency_cache[p.x][p.y] <= LIGHT_TRANSPARENCY_SOLID &&
675 get_player_character().pos().xy() != p;
676 };
677
678 const bool p_opaque = is_opaque( p.xy() );
679 float apparent_light;
680
681 if( p_opaque && vis > 0 ) {
682 // This is the complicated case. We want to check which quadrants the
683 // player can see the tile from, and only count light values from those
684 // quadrants.
685 struct offset_and_quadrants {
686 point offset;
687 std::array<quadrant, 2> quadrants;
688 };
689 static constexpr std::array<offset_and_quadrants, 8> adjacent_offsets = {{
698 }
699 };
700
701 four_quadrants seen_from( 0 );
702 for( const offset_and_quadrants &oq : adjacent_offsets ) {
703 const point neighbour = p.xy() + oq.offset;
704
705 if( !lightmap_boundaries.contains( neighbour ) ) {
706 continue;
707 }
708 if( is_opaque( neighbour ) ) {
709 continue;
710 }
711 if( map_cache.seen_cache[neighbour.x][neighbour.y] == 0 &&
712 map_cache.camera_cache[neighbour.x][neighbour.y] == 0 ) {
713 continue;
714 }
715 // This is a non-opaque visible neighbour, so count visibility from the relevant
716 // quadrants
717 seen_from[oq.quadrants[0]] = vis;
718 seen_from[oq.quadrants[1]] = vis;
719 }
720 apparent_light = ( seen_from * map_cache.lm[p.x][p.y] ).max();
721 } else {
722 // This is the simple case, for a non-opaque tile light from all
723 // directions is equivalent
724 apparent_light = vis * map_cache.lm[p.x][p.y].max();
725 }
726 return { obstructed, apparent_light };
727}
const half_open_rectangle< point > lightmap_boundaries(lightmap_boundary_min, lightmap_boundary_max)
static constexpr float LIGHT_TRANSPARENCY_SOLID
Transparency 101: Transparency usually ranges between 0.038 (open air) and 0.38 (regular smoke).
Definition: lightmap.h:32
static constexpr point point_south_west
Definition: point.h:281
static constexpr point point_west
Definition: point.h:282
static constexpr point point_north_east
Definition: point.h:277
static constexpr point point_north_west
Definition: point.h:283
static constexpr point point_south_east
Definition: point.h:279
static constexpr point point_south
Definition: point.h:280
static constexpr point point_north
Definition: point.h:276
static constexpr point point_east
Definition: point.h:278
float seen_cache[MAPSIZE_X][MAPSIZE_Y]
Definition: map.h:343
float transparency_cache[MAPSIZE_X][MAPSIZE_Y]
Definition: map.h:332
float camera_cache[MAPSIZE_X][MAPSIZE_Y]
Definition: map.h:347
int y
Definition: point.h:39
int x
Definition: point.h:38

References level_cache::camera_cache, get_player_character(), LIGHT_TRANSPARENCY_SOLID, lightmap_boundaries, level_cache::lm, four_quadrants::max(), NE, NW, point_east, point_north, point_north_east, point_north_west, point_south, point_south_east, point_south_west, point_west, Character::pos(), SE, level_cache::seen_cache, SW, level_cache::transparency_cache, point::x, tripoint::x, tripoint::xy(), point::y, and tripoint::y.

Referenced by apparent_light_at(), pl_sees(), and editmap::update_view_with_help().

◆ apply_character_light()

void map::apply_character_light ( Character p)
protected

Definition at line 227 of file lightmap.cpp.

228{
229 if( p.has_effect( effect_onfire ) ) {
230 apply_light_source( p.pos(), 8 );
231 } else if( p.has_effect( effect_haslight ) ) {
232 apply_light_source( p.pos(), 4 );
233 }
234
235 const float held_luminance = p.active_light();
236 if( held_luminance > LIGHT_AMBIENT_LOW ) {
237 apply_light_source( p.pos(), held_luminance );
238 }
239
240 if( held_luminance >= 4 && held_luminance > ambient_light_at( p.pos() ) - 0.5f ) {
241 p.add_effect( effect_haslight, 1_turns );
242 }
243}
float active_light() const
Returns character luminosity based on the brightest active item they are carrying.
Definition: character.cpp:6377
void add_effect(const effect &eff, bool force=false, bool deferred=false)
Definition: creature.cpp:980
bool has_effect(const efftype_id &eff_id, body_part bp=num_bp) const
Check if creature has the matching effect.
Definition: creature.cpp:1179
void apply_light_source(const tripoint &p, float luminance)
Definition: lightmap.cpp:1543
float ambient_light_at(const tripoint &p) const
Definition: lightmap.cpp:646
static const efftype_id effect_haslight("haslight")
static const efftype_id effect_onfire("onfire")
static constexpr float LIGHT_AMBIENT_LOW
Definition: lightmap.h:14

References Character::active_light(), Creature::add_effect(), ambient_light_at(), apply_light_source(), effect_haslight, effect_onfire, Creature::has_effect(), LIGHT_AMBIENT_LOW, and Character::pos().

Referenced by generate_lightmap().

◆ apply_directional_light()

void map::apply_directional_light ( const tripoint p,
int  direction,
float  luminance 
)
private

Definition at line 1624 of file lightmap.cpp.

1625{
1626 const point p2( p.xy() );
1627
1628 auto &cache = get_cache( p.z );
1629 four_quadrants( &lm )[MAPSIZE_X][MAPSIZE_Y] = cache.lm;
1630 float ( &transparency_cache )[MAPSIZE_X][MAPSIZE_Y] = cache.transparency_cache;
1631 diagonal_blocks( &blocked_cache )[MAPSIZE_X][MAPSIZE_Y] = cache.vehicle_obscured_cache;
1632
1633 if( direction == 90 ) {
1634 castLight < 1, 0, 0, -1, float, four_quadrants, light_calc, light_check,
1636 lm, transparency_cache, blocked_cache, p2, 0, luminance );
1637 castLight < -1, 0, 0, -1, float, four_quadrants, light_calc, light_check,
1639 lm, transparency_cache, blocked_cache, p2, 0, luminance );
1640 } else if( direction == 0 ) {
1641 castLight < 0, -1, 1, 0, float, four_quadrants, light_calc, light_check,
1643 lm, transparency_cache, blocked_cache, p2, 0, luminance );
1644 castLight < 0, -1, -1, 0, float, four_quadrants, light_calc, light_check,
1646 lm, transparency_cache, blocked_cache, p2, 0, luminance );
1647 } else if( direction == 270 ) {
1648 castLight<1, 0, 0, 1, float, four_quadrants, light_calc, light_check,
1650 lm, transparency_cache, blocked_cache, p2, 0, luminance );
1651 castLight < -1, 0, 0, 1, float, four_quadrants, light_calc, light_check,
1653 lm, transparency_cache, blocked_cache, p2, 0, luminance );
1654 } else if( direction == 180 ) {
1655 castLight<0, 1, 1, 0, float, four_quadrants, light_calc, light_check,
1657 lm, transparency_cache, blocked_cache, p2, 0, luminance );
1658 castLight < 0, 1, -1, 0, float, four_quadrants, light_calc, light_check,
1660 lm, transparency_cache, blocked_cache, p2, 0, luminance );
1661 }
1662}
static constexpr int MAPSIZE_Y
static constexpr int MAPSIZE_X
void castLight(Out(&output_cache)[MAPSIZE_X][MAPSIZE_Y], const T(&input_array)[MAPSIZE_X][MAPSIZE_Y], const diagonal_blocks(&blocked_array)[MAPSIZE_X][MAPSIZE_Y], const point &offset, int offsetDistance, T numerator=VISIBILITY_FULL, int row=1, float start=1.0f, float end=0.0f, T cumulative_transparency=LIGHT_TRANSPARENCY_OPEN_AIR)
Definition: lightmap.cpp:1155
static bool light_check(const float &transparency, const float &intensity)
Definition: lightmap.cpp:1538
static float light_calc(const float &numerator, const float &transparency, const int &distance)
Definition: lightmap.cpp:1531
direction
Definition: line.h:39
void update_light_quadrants(four_quadrants &update, const float &new_value, quadrant q)
Definition: shadowcasting.h:97
float accumulate_transparency(const float &cumulative_transparency, const float &current_transparency, const int &distance)

References accumulate_transparency(), castLight(), get_cache(), light_calc(), light_check(), MAPSIZE_X, MAPSIZE_Y, update_light_quadrants(), tripoint::xy(), and tripoint::z.

Referenced by generate_lightmap().

◆ apply_faction_ownership()

void map::apply_faction_ownership ( const point p1,
const point p2,
const faction_id id 
)

Definition at line 5501 of file mapgen.cpp.

5502{
5503 for( const tripoint &p : points_in_rectangle( tripoint( p1, abs_sub.z ), tripoint( p2,
5504 abs_sub.z ) ) ) {
5505 auto items = i_at( p.xy() );
5506 for( item &elem : items ) {
5507 elem.set_owner( id );
5508 }
5509 vehicle *source_veh = veh_pointer_or_null( veh_at( p ) );
5510 if( source_veh ) {
5511 if( !source_veh->has_owner() ) {
5512 source_veh->set_owner( id );
5513 }
5514 }
5515 }
5516}
tripoint_range< tripoint > points_in_rectangle(const tripoint &from, const tripoint &to) const
Definition: map.cpp:8607
bool has_owner() const
Definition: vehicle.h:844
void set_owner(const faction_id &new_owner)
Definition: vehicle.h:831

References abs_sub, vehicle::has_owner(), i_at(), points_in_rectangle(), vehicle::set_owner(), veh_at(), veh_pointer_or_null(), and tripoint::z.

Referenced by jmapgen_faction::apply().

◆ apply_light_arc()

void map::apply_light_arc ( const tripoint p,
units::angle  angle,
float  luminance,
units::angle  wideangle = 30_degrees 
)
private

Definition at line 1664 of file lightmap.cpp.

1666{
1667 if( luminance <= LIGHT_SOURCE_LOCAL ) {
1668 return;
1669 }
1670
1671 bool lit[LIGHTMAP_CACHE_X][LIGHTMAP_CACHE_Y] {};
1672
1674
1675 // Normalize (should work with negative values too)
1676 const units::angle wangle = wideangle / 2.0;
1677
1678 units::angle nangle = fmod( angle, 360_degrees );
1679
1680 tripoint end;
1681 int range = LIGHT_RANGE( luminance );
1682 calc_ray_end( nangle, range, p, end );
1683 apply_light_ray( lit, p, end, luminance );
1684
1685 tripoint test;
1686 calc_ray_end( wangle + nangle, range, p, test );
1687
1688 const float wdist = hypot( end.x - test.x, end.y - test.y );
1689 if( wdist <= 0.5 ) {
1690 return;
1691 }
1692
1693 // attempt to determine beam intensity required to cover all squares
1694 const units::angle wstep = ( wangle / ( wdist * M_SQRT2 ) );
1695
1696 // NOLINTNEXTLINE(clang-analyzer-security.FloatLoopCounter)
1697 for( units::angle ao = wstep; ao <= wangle; ao += wstep ) {
1698 if( trigdist ) {
1699 double fdist = ( ao * M_PI_2 ) / wangle;
1700 end.x = static_cast<int>(
1701 p.x + ( static_cast<double>( range ) - fdist * 2.0 ) * cos( nangle + ao ) );
1702 end.y = static_cast<int>(
1703 p.y + ( static_cast<double>( range ) - fdist * 2.0 ) * sin( nangle + ao ) );
1704 apply_light_ray( lit, p, end, luminance );
1705
1706 end.x = static_cast<int>(
1707 p.x + ( static_cast<double>( range ) - fdist * 2.0 ) * cos( nangle - ao ) );
1708 end.y = static_cast<int>(
1709 p.y + ( static_cast<double>( range ) - fdist * 2.0 ) * sin( nangle - ao ) );
1710 apply_light_ray( lit, p, end, luminance );
1711 } else {
1712 calc_ray_end( nangle + ao, range, p, end );
1713 apply_light_ray( lit, p, end, luminance );
1714 calc_ray_end( nangle - ao, range, p, end );
1715 apply_light_ray( lit, p, end, luminance );
1716 }
1717 }
1718}
bool trigdist
Circular distances.
void apply_light_ray(bool lit[MAPSIZE_X][MAPSIZE_Y], const tripoint &s, const tripoint &e, float luminance)
Definition: lightmap.cpp:1720
static constexpr int LIGHTMAP_CACHE_Y
Definition: lightmap.cpp:49
static constexpr int LIGHTMAP_CACHE_X
Definition: lightmap.cpp:48
static constexpr float LIGHT_SOURCE_LOCAL
Definition: lightmap.h:8
#define LIGHT_RANGE(b)
Definition: lightmap.h:41
void calc_ray_end(units::angle angle, const int range, const tripoint &p, tripoint &out)
Definition: line.cpp:751
#define M_SQRT2
Definition: math_defines.h:29
#define M_PI_2
Definition: math_defines.h:25
quantity< double, angle_in_radians_tag > angle
Definition: units_angle.h:17
double sin(angle a)
Definition: units_angle.h:52
double cos(angle a)
Definition: units_angle.h:57
quantity< V, U > fmod(quantity< V, U > num, quantity< V, U > den)
Definition: units_def.h:142

References apply_light_ray(), apply_light_source(), calc_ray_end(), units::cos(), units::fmod(), LIGHT_RANGE, LIGHT_SOURCE_LOCAL, LIGHTMAP_CACHE_X, LIGHTMAP_CACHE_Y, M_PI_2, M_SQRT2, units::sin(), trigdist, tripoint::x, and tripoint::y.

Referenced by add_light_from_items(), and generate_lightmap().

◆ apply_light_ray()

void map::apply_light_ray ( bool  lit[MAPSIZE_X][MAPSIZE_Y],
const tripoint s,
const tripoint e,
float  luminance 
)
private

Definition at line 1720 of file lightmap.cpp.

1722{
1723 point a( std::abs( e.x - s.x ) * 2, std::abs( e.y - s.y ) * 2 );
1724 point d( ( s.x < e.x ) ? 1 : -1, ( s.y < e.y ) ? 1 : -1 );
1725 point p( s.xy() );
1726
1727 quadrant quad = quadrant_from_x_y( d.x, d.y );
1728
1729 // TODO: Invert that z comparison when it's sane
1730 if( s.z != e.z || ( s.x == e.x && s.y == e.y ) ) {
1731 return;
1732 }
1733
1734 auto &lm = get_cache( s.z ).lm;
1735 auto &transparency_cache = get_cache( s.z ).transparency_cache;
1736
1737 float distance = 1.0;
1738 float transparency = LIGHT_TRANSPARENCY_OPEN_AIR;
1739 const float scaling_factor = static_cast<float>( rl_dist( s, e ) ) /
1740 static_cast<float>( square_dist( s, e ) );
1741 // TODO: [lightmap] Pull out the common code here rather than duplication
1742 if( a.x > a.y ) {
1743 int t = a.y - ( a.x / 2 );
1744 do {
1745 if( t >= 0 ) {
1746 p.y += d.y;
1747 t -= a.x;
1748 }
1749
1750 p.x += d.x;
1751 t += a.y;
1752
1753 // TODO: clamp coordinates to map bounds before this method is called.
1754 if( lightmap_boundaries.contains( p ) ) {
1755 float current_transparency = transparency_cache[p.x][p.y];
1756 bool is_opaque = ( current_transparency == LIGHT_TRANSPARENCY_SOLID );
1757 if( !lit[p.x][p.y] ) {
1758 // Multiple rays will pass through the same squares so we need to record that
1759 lit[p.x][p.y] = true;
1760 float lm_val = luminance / ( fastexp( transparency * distance ) * distance );
1761 quadrant q = is_opaque ? quad : quadrant::default_;
1762 lm[p.x][p.y][q] = std::max( lm[p.x][p.y][q], lm_val );
1763 }
1764 if( is_opaque ) {
1765 break;
1766 }
1767 // Cumulative average of the transparency values encountered.
1768 transparency = ( ( distance - 1.0 ) * transparency + current_transparency ) / distance;
1769 } else {
1770 break;
1771 }
1772
1773 distance += scaling_factor;
1774 } while( !( p.x == e.x && p.y == e.y ) );
1775 } else {
1776 int t = a.x - ( a.y / 2 );
1777 do {
1778 if( t >= 0 ) {
1779 p.x += d.x;
1780 t -= a.y;
1781 }
1782
1783 p.y += d.y;
1784 t += a.x;
1785
1786 if( lightmap_boundaries.contains( p ) ) {
1787 float current_transparency = transparency_cache[p.x][p.y];
1788 bool is_opaque = ( current_transparency == LIGHT_TRANSPARENCY_SOLID );
1789 if( !lit[p.x][p.y] ) {
1790 // Multiple rays will pass through the same squares so we need to record that
1791 lit[p.x][p.y] = true;
1792 float lm_val = luminance / ( fastexp( transparency * distance ) * distance );
1793 quadrant q = is_opaque ? quad : quadrant::default_;
1794 lm[p.x][p.y][q] = std::max( lm[p.x][p.y][q], lm_val );
1795 }
1796 if( is_opaque ) {
1797 break;
1798 }
1799 // Cumulative average of the transparency values encountered.
1800 transparency = ( ( distance - 1.0 ) * transparency + current_transparency ) / distance;
1801 } else {
1802 break;
1803 }
1804
1805 distance += scaling_factor;
1806 } while( !( p.x == e.x && p.y == e.y ) );
1807 }
1808}
int square_dist(const coords::coord_point< Point, Origin, Scale > &loc1, const coords::coord_point< Point, Origin, Scale > &loc2)
Definition: coordinates.h:505
static constexpr quadrant quadrant_from_x_y(int x, int y)
Definition: lightmap.cpp:815
static float fastexp(float x)
Definition: lightmap.cpp:1515
static constexpr float LIGHT_TRANSPARENCY_OPEN_AIR
Definition: lightmap.h:36
quadrant
Definition: shadowcasting.h:22

References a, default_, fastexp(), get_cache(), LIGHT_TRANSPARENCY_OPEN_AIR, LIGHT_TRANSPARENCY_SOLID, lightmap_boundaries, level_cache::lm, quadrant_from_x_y(), rl_dist(), square_dist(), level_cache::transparency_cache, point::x, tripoint::x, tripoint::xy(), point::y, tripoint::y, and tripoint::z.

Referenced by apply_light_arc().

◆ apply_light_source()

void map::apply_light_source ( const tripoint p,
float  luminance 
)
private

Definition at line 1543 of file lightmap.cpp.

1544{
1545 auto &cache = get_cache( p.z );
1546 four_quadrants( &lm )[MAPSIZE_X][MAPSIZE_Y] = cache.lm;
1547 float ( &sm )[MAPSIZE_X][MAPSIZE_Y] = cache.sm;
1548 float ( &transparency_cache )[MAPSIZE_X][MAPSIZE_Y] = cache.transparency_cache;
1549 float ( &light_source_buffer )[MAPSIZE_X][MAPSIZE_Y] = cache.light_source_buffer;
1550 diagonal_blocks( &blocked_cache )[MAPSIZE_X][MAPSIZE_Y] = cache.vehicle_obscured_cache;
1551
1552 const point p2( p.xy() );
1553
1554 if( inbounds( p ) ) {
1555 const float min_light = std::max( static_cast<float>( lit_level::LOW ), luminance );
1556 lm[p2.x][p2.y] = elementwise_max( lm[p2.x][p2.y], min_light );
1557 sm[p2.x][p2.y] = std::max( sm[p2.x][p2.y], luminance );
1558 }
1559 if( luminance <= lit_level::LOW ) {
1560 return;
1561 } else if( luminance <= lit_level::BRIGHT_ONLY ) {
1562 luminance = 1.49f;
1563 }
1564
1565 /* If we're a 5 luminance fire , we skip casting rays into ey && sx if we have
1566 neighboring fires to the north and west that were applied via light_source_buffer
1567 If there's a 1 luminance candle east in buffer, we still cast rays into ex since it's smaller
1568 If there's a 100 luminance magnesium flare south added via apply_light_source instead od
1569 add_light_source, it's unbuffered so we'll still cast rays into sy.
1570
1571 ey
1572 nnnNnnn
1573 w e
1574 w 5 +e
1575 sx W 5*1+E ex
1576 w ++++e
1577 w+++++e
1578 sssSsss
1579 sy
1580 */
1581 const int peer_inbounds = LIGHTMAP_CACHE_X - 1;
1582 bool north = ( p2.y != 0 && light_source_buffer[p2.x][p2.y - 1] < luminance );
1583 bool south = ( p2.y != peer_inbounds && light_source_buffer[p2.x][p2.y + 1] < luminance );
1584 bool east = ( p2.x != peer_inbounds && light_source_buffer[p2.x + 1][p2.y] < luminance );
1585 bool west = ( p2.x != 0 && light_source_buffer[p2.x - 1][p2.y] < luminance );
1586
1587 if( north ) {
1588 castLight < 1, 0, 0, -1, float, four_quadrants, light_calc, light_check,
1590 lm, transparency_cache, blocked_cache, p2, 0, luminance );
1591 castLight < -1, 0, 0, -1, float, four_quadrants, light_calc, light_check,
1593 lm, transparency_cache, blocked_cache, p2, 0, luminance );
1594 }
1595
1596 if( east ) {
1597 castLight < 0, -1, 1, 0, float, four_quadrants, light_calc, light_check,
1599 lm, transparency_cache, blocked_cache, p2, 0, luminance );
1600 castLight < 0, -1, -1, 0, float, four_quadrants, light_calc, light_check,
1602 lm, transparency_cache, blocked_cache, p2, 0, luminance );
1603 }
1604
1605 if( south ) {
1606 castLight<1, 0, 0, 1, float, four_quadrants, light_calc, light_check,
1608 lm, transparency_cache, blocked_cache, p2, 0, luminance );
1609 castLight < -1, 0, 0, 1, float, four_quadrants, light_calc, light_check,
1611 lm, transparency_cache, blocked_cache, p2, 0, luminance );
1612 }
1613
1614 if( west ) {
1615 castLight<0, 1, 1, 0, float, four_quadrants, light_calc, light_check,
1617 lm, transparency_cache, blocked_cache, p2, 0, luminance );
1618 castLight < 0, 1, -1, 0, float, four_quadrants, light_calc, light_check,
1620 lm, transparency_cache, blocked_cache, p2, 0, luminance );
1621 }
1622}
constexpr scale sm
Definition: coordinates.h:31

References accumulate_transparency(), BRIGHT_ONLY, castLight(), get_cache(), inbounds(), light_calc(), light_check(), LIGHTMAP_CACHE_X, LOW, MAPSIZE_X, MAPSIZE_Y, coords::sm, update_light_quadrants(), point::x, tripoint::xy(), point::y, and tripoint::z.

Referenced by apply_character_light(), apply_light_arc(), and generate_lightmap().

◆ apply_vision_transparency_cache()

void map::apply_vision_transparency_cache ( const tripoint center,
int  target_z,
float(&)  vision_restore_cache[9],
bool(&)  blocked_restore_cache[8] 
)
protected

Definition at line 1313 of file lightmap.cpp.

1315{
1316 level_cache &map_cache = get_cache( target_z );
1317 float ( &transparency_cache )[MAPSIZE_X][MAPSIZE_Y] = map_cache.transparency_cache;
1318 diagonal_blocks( &blocked_cache )[MAPSIZE_X][MAPSIZE_Y] = map_cache.vehicle_obscured_cache;
1319
1320 int i = 0;
1321 for( const point &adjacent : eight_adjacent_offsets ) {
1322 const tripoint p = center + adjacent;
1323 if( !inbounds( p ) ) {
1324 continue;
1325 }
1326 vision_restore_cache[i] = transparency_cache[p.x][p.y];
1328 transparency_cache[p.x][p.y] = LIGHT_TRANSPARENCY_SOLID;
1330
1332 adjacent ) == four_diagonal_offsets.end() ) {
1333 debugmsg( "Hidden tile not on a diagonal" );
1334 continue;
1335 }
1336
1337 bool &relevant_blocked = adjacent == point_north_east ? blocked_cache[center.x][center.y].ne :
1338 adjacent == point_south_east ? blocked_cache[p.x][p.y].nw :
1339 adjacent == point_south_west ? blocked_cache[p.x][p.y].ne :
1340 /* point_north_west */ blocked_cache[center.x][center.y].nw;
1341
1342 //We only set the restore cache if we actually flip the bit
1343 blocked_restore_cache[i] = !relevant_blocked;
1344
1345 relevant_blocked = true;
1346 }
1347 i++;
1348 }
1349 vision_restore_cache[8] = transparency_cache[center.x][center.y];
1350}
vision_adjustment vision_transparency_cache[8]
Definition: map.h:1834
@ VISION_ADJUST_HIDDEN
Definition: lightmap.h:79
@ VISION_ADJUST_SOLID
Definition: lightmap.h:78
FMT_CONSTEXPR bool find(Ptr first, Ptr last, T value, Ptr &out)
static constexpr std::array< point, 8 > eight_adjacent_offsets
Definition: point.h:366
static constexpr std::array< point, 4 > four_diagonal_offsets
Definition: point.h:362
diagonal_blocks vehicle_obscured_cache[MAPSIZE_X][MAPSIZE_Y]
Definition: map.h:336

References center, debugmsg, eight_adjacent_offsets, detail::find(), four_diagonal_offsets, get_cache(), inbounds(), LIGHT_TRANSPARENCY_SOLID, MAPSIZE_X, MAPSIZE_Y, point_north_east, point_south_east, point_south_west, level_cache::transparency_cache, level_cache::vehicle_obscured_cache, VISION_ADJUST_HIDDEN, VISION_ADJUST_SOLID, vision_transparency_cache, tripoint::x, and tripoint::y.

Referenced by build_seen_cache().

◆ bash()

bash_results map::bash ( const tripoint p,
int  str,
bool  silent = false,
bool  destroy = false,
bool  bash_floor = false,
const vehicle bashing_vehicle = nullptr 
)

Returns a pair where first is whether anything was smashed and second is if it was destroyed.

Parameters
pWhere to bash
strHow hard to bash
silentDon't produce any sound
destroyDestroys some otherwise unbashable tiles
bash_floorAllow bashing the floor and the tile that supports it
bashing_vehicleVehicle that should NOT be bashed (because it is doing the bashing)

Definition at line 3527 of file map.cpp.

3530{
3531 bash_params bsh{
3532 str, silent, destroy, bash_floor, static_cast<float>( rng_float( 0, 1.0f ) ), false, true
3533 };
3535 if( !inbounds( p ) ) {
3536 return result;
3537 }
3538
3539 bool bashed_sealed = false;
3540 if( has_flag( "SEALED", p ) ) {
3541 result |= bash_ter_furn( p, bsh );
3542 bashed_sealed = true;
3543 }
3544
3545 result |= bash_field( p, bsh );
3546
3547 // Don't bash items inside terrain/furniture with SEALED flag
3548 if( !bashed_sealed ) {
3549 result |= bash_items( p, bsh );
3550 }
3551 // Don't bash the vehicle doing the bashing
3552 const vehicle *veh = veh_pointer_or_null( veh_at( p ) );
3553 if( veh != nullptr && veh != bashing_vehicle ) {
3554 result |= bash_vehicle( p, bsh );
3555 }
3556
3557 // If we still didn't bash anything solid (a vehicle) or a tile with SEALED flag, bash ter/furn
3558 if( !result.bashed_solid && !bashed_sealed ) {
3559 result |= bash_ter_furn( p, bsh );
3560 }
3561
3562 return result;
3563}
bash_results bash_field(const tripoint &p, const bash_params &params)
Definition: map.cpp:3617
bash_results bash_items(const tripoint &p, const bash_params &params)
Definition: map.cpp:3565
bash_results bash_vehicle(const tripoint &p, const bash_params &params)
Definition: map.cpp:3599
bash_results bash_ter_furn(const tripoint &p, const bash_params &params)
Definition: map.cpp:3403
double rng_float(double lo, double hi)
Definition: rng.cpp:28
@ silent
Definition: weather_type.h:56

References bash_field(), bash_items(), bash_ter_furn(), bash_vehicle(), destroy(), has_flag(), inbounds(), rng_float(), silent, veh_at(), and veh_pointer_or_null().

Referenced by Character::activate_bionic(), jmapgen_setmap::apply(), spell_effect::bash(), bash_furn_success(), bash_resistance(), bash_strength(), bash_ter_furn(), bash_ter_success(), batter(), destroy(), destroy_furn(), explosion_handler::do_blast(), drop_furniture(), drop_items(), game::fling_creature(), is_bashable(), game::knockback(), npc::move_to(), vehicle::part_collision(), player::reach_attack(), route(), scatter_chunks(), shoot(), explosion_handler::shrapnel(), mattack::shriek_stun(), smash(), and valid_move().

◆ bash_field()

bash_results map::bash_field ( const tripoint p,
const bash_params params 
)

Definition at line 3617 of file map.cpp.

3618{
3620 if( get_field( p, fd_web ) != nullptr ) {
3621 result.did_bash = true;
3622 result.bashed_solid = true; // To prevent bashing furniture/vehicles
3623 remove_field( p, fd_web );
3624 }
3625
3626 return result;
3627}
void remove_field(const tripoint &p, const field_type_id &field_to_remove)
Remove field entry at xy, ignored if the field entry is not present.
Definition: map.cpp:5465
field_type_id fd_web
Definition: field_type.cpp:340

References fd_web, get_field(), and remove_field().

Referenced by bash().

◆ bash_furn_success()

bash_results map::bash_furn_success ( const tripoint p,
const bash_params params 
)

Definition at line 3303 of file map.cpp.

3304{
3306 const auto &furnid = furn( p ).obj();
3307 const map_bash_info &bash = furnid.bash;
3308
3309
3310 if( has_flag_furn( "FUNGUS", p ) ) {
3311 fungal_effects( *g, *this ).create_spores( p );
3312 }
3313 if( has_flag_furn( "MIGO_NERVE", p ) ) {
3314 map_funcs::migo_nerve_cage_removal( *this, p, true );
3315 }
3316 std::string soundfxvariant = furnid.id.str();
3317 const bool tent = !bash.tent_centers.empty();
3318
3319 // Special code to collapse the tent if destroyed
3320 if( tent ) {
3321 // Get ids of possible centers
3322 std::set<furn_id> centers;
3323 for( const auto &cur_id : bash.tent_centers ) {
3324 if( cur_id.is_valid() ) {
3325 centers.insert( cur_id );
3326 }
3327 }
3328
3330
3331 // Find the center of the tent
3332 // First check if we're not currently bashing the center
3333 if( centers.count( furn( p ) ) > 0 ) {
3334 tentp.emplace( p, furn( p ) );
3335 } else {
3336 for( const tripoint &pt : points_in_radius( p, bash.collapse_radius ) ) {
3337 const furn_id &f_at = furn( pt );
3338 // Check if we found the center of the current tent
3339 if( centers.count( f_at ) > 0 ) {
3340 tentp.emplace( pt, f_at );
3341 break;
3342 }
3343 }
3344 }
3345 // Didn't find any tent center, wreck the current tile
3346 if( !tentp ) {
3348 furn_set( p, bash.furn_set );
3349 } else {
3350 // Take the tent down
3351 const int rad = tentp->second.obj().bash.collapse_radius;
3352 for( const tripoint &pt : points_in_radius( tentp->first, rad ) ) {
3353 const furn_id frn = furn( pt );
3354 if( frn == f_null ) {
3355 continue;
3356 }
3357
3358 const map_bash_info &recur_bash = frn.obj().bash;
3359 // Check if we share a center type and thus a "tent type"
3360 for( const auto &cur_id : recur_bash.tent_centers ) {
3361 if( centers.count( cur_id.id() ) > 0 ) {
3362 // Found same center, wreck current tile
3364 furn_set( pt, recur_bash.furn_set );
3365 break;
3366 }
3367 }
3368 }
3369 }
3370 soundfxvariant = "smash_cloth";
3371 } else {
3372 furn_set( p, bash.furn_set );
3373 for( item &it : i_at( p ) ) {
3374 it.on_drop( p, *this );
3375 }
3376 // HACK: Hack alert.
3377 // Signs have cosmetics associated with them on the submap since
3378 // furniture can't store dynamic data to disk. To prevent writing
3379 // mysteriously appearing for a sign later built here, remove the
3380 // writing from the submap.
3381 delete_signage( p );
3382 }
3383
3384 if( !tent ) {
3386 }
3387
3388 if( !bash.sound.empty() && !params.silent ) {
3389 static const std::string soundfxid = "smash_success";
3390 int sound_volume = get_sound_volume( bash );
3391 sounds::sound( p, sound_volume, sounds::sound_t::combat, bash.sound, false,
3392 soundfxid, soundfxvariant );
3393 }
3394
3395 if( bash.explosive > 0 ) {
3396 // TODO implement if the player triggered the explosive furniture
3397 explosion_handler::explosion( p, nullptr, bash.explosive, 0.8, false );
3398 }
3399
3400 return result;
3401}
T & emplace(Args &&... args)
Definition: optional.h:146
void create_spores(const tripoint &p, Creature *origin=nullptr)
Makes spores at p.
bool has_flag_furn(const std::string &flag, const tripoint &p) const
Definition: map.cpp:2317
bash_results bash(const tripoint &p, int str, bool silent=false, bool destroy=false, bool bash_floor=false, const vehicle *bashing_vehicle=nullptr)
Returns a pair where first is whether anything was smashed and second is if it was destroyed.
Definition: map.cpp:3527
std::vector< item * > spawn_items(const tripoint &p, const std::vector< item > &new_items)
Definition: map.cpp:4163
void furn_set(const tripoint &p, const furn_id &new_furniture, cata::poly_serialized< active_tile_data > new_active=nullptr)
Sets the furniture at given position.
Definition: map.cpp:1360
void delete_signage(const tripoint &p) const
Definition: map.cpp:4022
static int get_sound_volume(const map_bash_info &bash)
Definition: map.cpp:3165
furn_id f_null
Definition: mapdata.cpp:1095
void explosion(const tripoint &p, Creature *source, float power, float factor, bool fire, int legacy_casing_mass, float)
Legacy explosion function.
Definition: explosion.cpp:785
ItemList items_from(const item_group_id &group_id, const time_point &birthday)
Create items from the given group.
Definition: item_group.cpp:574
void migo_nerve_cage_removal(map &m, const tripoint &p, bool spawn_damaged)
void sound(const tripoint &p, int vol, sound_t category, const std::string &description, bool ambient=false, const std::string &id="", const std::string &variant="default")
Sound at (p) of intensity (vol)
Definition: sounds.cpp:177
bool silent
Definition: map.h:136
std::vector< furn_str_id > tent_centers
Definition: mapdata.h:100
item_group_id drop_group
Definition: mapdata.h:86
furn_str_id furn_set
Definition: mapdata.h:98
map_bash_info bash
Definition: mapdata.h:344

References bash(), map_data_common_t::bash, sounds::combat, fungal_effects::create_spores(), delete_signage(), map_bash_info::drop_group, cata::optional< T >::emplace(), explosion_handler::explosion(), f_null, furn(), furn_set(), map_bash_info::furn_set, g, get_sound_volume(), has_flag_furn(), i_at(), item_group::items_from(), map_funcs::migo_nerve_cage_removal(), int_id< T >::obj(), points_in_radius(), bash_params::silent, sounds::sound(), spawn_items(), map_bash_info::tent_centers, and calendar::turn.

Referenced by bash_ter_furn().

◆ bash_items()

bash_results map::bash_items ( const tripoint p,
const bash_params params 
)

Definition at line 3565 of file map.cpp.

3566{
3568 if( !has_items( p ) ) {
3569 return result;
3570 }
3571
3572 std::vector<item> smashed_contents;
3573 auto bashed_items = i_at( p );
3574 bool smashed_glass = false;
3575 for( auto bashed_item = bashed_items.begin(); bashed_item != bashed_items.end(); ) {
3576 // the check for active suppresses Molotovs smashing themselves with their own explosion
3577 if( bashed_item->made_of( material_id( "glass" ) ) && !bashed_item->active && one_in( 2 ) ) {
3578 result.did_bash = true;
3579 smashed_glass = true;
3580 for( const item *bashed_content : bashed_item->contents.all_items_top() ) {
3581 smashed_contents.push_back( item( *bashed_content ) );
3582 }
3583 bashed_item = bashed_items.erase( bashed_item );
3584 } else {
3585 ++bashed_item;
3586 }
3587 }
3588 // Now plunk in the contents of the smashed items.
3589 spawn_items( p, smashed_contents );
3590
3591 // Add a glass sound even when something else also breaks
3592 if( smashed_glass && !params.silent ) {
3593 sounds::sound( p, 12, sounds::sound_t::combat, _( "glass shattering" ), false,
3594 "smash_success", "smash_glass_contents" );
3595 }
3596 return result;
3597}
std::list< item * > all_items_top()
returns a list of pointers to all top-level items
item_contents contents
Definition: item.h:2158
bool has_items(const tripoint &p) const
Checks for existence of items.
Definition: map.cpp:4771

References _, item_contents::all_items_top(), sounds::combat, item::contents, has_items(), i_at(), one_in(), bash_params::silent, sounds::sound(), and spawn_items().

Referenced by bash().

◆ bash_rating() [1/2]

int map::bash_rating ( const int  str,
const point p 
) const
inline

Definition at line 1052 of file map.h.

1052 {
1053 return bash_rating( str, tripoint( p, abs_sub.z ) );
1054 }
int bash_rating(int str, const tripoint &p, bool allow_floor=false) const
Returns a success rating from -1 to 10 for a given tile based on a set strength, used for AI movement...
Definition: map.cpp:2488

References abs_sub, bash_rating(), and tripoint::z.

◆ bash_rating() [2/2]

int map::bash_rating ( int  str,
const tripoint p,
bool  allow_floor = false 
) const

Returns a success rating from -1 to 10 for a given tile based on a set strength, used for AI movement planning Values roughly correspond to 10% increment chances of success on a given bash, rounded down.

-1 means the square is not bashable

Definition at line 2488 of file map.cpp.

2489{
2490 if( !inbounds( p ) ) {
2491 dbg( DL::Warn ) << "Looking for out-of-bounds is_bashable at " << p;
2492 return -1;
2493 }
2494
2495 if( str <= 0 ) {
2496 return -1;
2497 }
2498
2499 const furn_t &furniture = furn( p ).obj();
2500 const ter_t &terrain = ter( p ).obj();
2501 const optional_vpart_position vp = veh_at( p );
2502 vehicle *const veh = vp ? &vp->vehicle() : nullptr;
2503 const int part = vp ? vp->part_index() : -1;
2504 return bash_rating_internal( str, furniture, terrain, allow_floor, veh, part );
2505}
int bash_rating_internal(int str, const furn_t &furniture, const ter_t &terrain, bool allow_floor, const vehicle *veh, int part) const
Definition: map.cpp:2380

References bash_rating_internal(), dbg, furn(), furniture, inbounds(), int_id< T >::obj(), ter(), terrain, veh_at(), and Warn.

Referenced by bash_rating(), npc::can_move_to(), monster::move(), and npc::move_to().

◆ bash_rating_internal()

int map::bash_rating_internal ( int  str,
const furn_t furniture,
const ter_t terrain,
bool  allow_floor,
const vehicle veh,
int  part 
) const
private
Strength determines what furniture can be smashed Strength determines what terrain can be smashed Strength increases smashing damage

Definition at line 2380 of file map.cpp.

2383{
2384 bool furn_smash = false;
2385 bool ter_smash = false;
2386 ///\EFFECT_STR determines what furniture can be smashed
2387 if( furniture.id && furniture.bash.str_max != -1 ) {
2388 furn_smash = true;
2389 ///\EFFECT_STR determines what terrain can be smashed
2390 } else if( terrain.bash.str_max != -1 && ( !terrain.bash.bash_below || allow_floor ) ) {
2391 ter_smash = true;
2392 }
2393
2394 if( veh != nullptr && vpart_position( const_cast<vehicle &>( *veh ), part ).obstacle_at_part() ) {
2395 // Monsters only care about rating > 0, NPCs should want to path around cars instead
2396 return 2; // Should probably be a function of part hp (+armor on tile)
2397 }
2398
2399 int bash_min = 0;
2400 int bash_max = 0;
2401 if( furn_smash ) {
2402 bash_min = furniture.bash.str_min;
2403 bash_max = furniture.bash.str_max;
2404 } else if( ter_smash ) {
2405 bash_min = terrain.bash.str_min;
2406 bash_max = terrain.bash.str_max;
2407 } else {
2408 return -1;
2409 }
2410
2411 ///\EFFECT_STR increases smashing damage
2412 if( str < bash_min ) {
2413 return 0;
2414 } else if( str >= bash_max ) {
2415 return 10;
2416 }
2417
2418 int ret = ( 10 * ( str - bash_min ) ) / ( bash_max - bash_min );
2419 // Round up to 1, so that desperate NPCs can try to bash down walls
2420 return std::max( ret, 1 );
2421}
Reference to a position (a point) of the vehicle.

References furniture, cata::hash64_detail::ret, and terrain.

Referenced by bash_rating(), and route().

◆ bash_resistance() [1/2]

int map::bash_resistance ( const point p) const
inline

Definition at line 1046 of file map.h.

1046 {
1047 return bash_resistance( tripoint( p, abs_sub.z ) );
1048 }
int bash_resistance(const tripoint &p, bool allow_floor=false) const
Returns min_str of the furniture or terrain at p.
Definition: map.cpp:2474

References abs_sub, bash_resistance(), and tripoint::z.

◆ bash_resistance() [2/2]

int map::bash_resistance ( const tripoint p,
bool  allow_floor = false 
) const

Returns min_str of the furniture or terrain at p.

Definition at line 2474 of file map.cpp.

2475{
2476 if( has_furn( p ) && furn( p ).obj().bash.str_min != -1 ) {
2477 return furn( p ).obj().bash.str_min;
2478 }
2479
2480 const auto &ter_bash = ter( p ).obj().bash;
2481 if( ter_bash.str_min != -1 && ( !ter_bash.bash_below || allow_floor ) ) {
2482 return ter_bash.str_min;
2483 }
2484
2485 return -1;
2486}
bool has_furn(const tripoint &p) const
Definition: map.cpp:1343
int str_min
Definition: mapdata.h:62

References bash(), map_data_common_t::bash, furn(), has_furn(), int_id< T >::obj(), map_bash_info::str_min, and ter().

Referenced by bash_resistance(), ranged::expected_coverage(), vehicle::part_collision(), rate_location(), smash(), and terrain_collision_data().

◆ bash_strength() [1/2]

int map::bash_strength ( const point p) const
inline

Definition at line 1041 of file map.h.

1041 {
1042 return bash_strength( tripoint( p, abs_sub.z ) );
1043 }
int bash_strength(const tripoint &p, bool allow_floor=false) const
Returns max_str of the furniture or terrain at p.
Definition: map.cpp:2460

References abs_sub, bash_strength(), and tripoint::z.

◆ bash_strength() [2/2]

int map::bash_strength ( const tripoint p,
bool  allow_floor = false 
) const

Returns max_str of the furniture or terrain at p.

Definition at line 2460 of file map.cpp.

2461{
2462 if( has_furn( p ) && furn( p ).obj().bash.str_max != -1 ) {
2463 return furn( p ).obj().bash.str_max;
2464 }
2465
2466 const auto &ter_bash = ter( p ).obj().bash;
2467 if( ter_bash.str_max != -1 && ( !ter_bash.bash_below || allow_floor ) ) {
2468 return ter_bash.str_max;
2469 }
2470
2471 return -1;
2472}
int str_max
Definition: mapdata.h:64

References bash(), map_data_common_t::bash, furn(), has_furn(), int_id< T >::obj(), map_bash_info::str_max, and ter().

Referenced by bash_strength(), ranged::expected_coverage(), game::fling_creature(), and terrain_collision_data().

◆ bash_ter_furn()

bash_results map::bash_ter_furn ( const tripoint p,
const bash_params params 
)

Definition at line 3403 of file map.cpp.

3404{
3406 std::string soundfxvariant;
3407 const auto &ter_obj = ter( p ).obj();
3408 const auto &furn_obj = furn( p ).obj();
3409 bool smash_ter = false;
3410 const map_bash_info *bash = nullptr;
3411
3412 if( furn_obj.id && furn_obj.bash.str_max != -1 ) {
3413 bash = &furn_obj.bash;
3414 soundfxvariant = furn_obj.id.str();
3415 } else if( ter_obj.bash.str_max != -1 ) {
3416 bash = &ter_obj.bash;
3417 smash_ter = true;
3418 soundfxvariant = ter_obj.id.str();
3419 }
3420
3421 // Floor bashing check
3422 // Only allow bashing floors when we want to bash floors and we're in z-level mode
3423 // Unless we're destroying, then it gets a little weird
3424 if( smash_ter && bash->bash_below && ( !zlevels || !params.bash_floor ) ) {
3425 if( !params.destroy ) {
3426 smash_ter = false;
3427 bash = nullptr;
3428 } else if( !bash->ter_set && zlevels ) {
3429 // HACK: A hack for destroy && !bash_floor
3430 // We have to check what would we create and cancel if it is what we have now
3431 tripoint below( p.xy(), p.z - 1 );
3432 const auto roof = get_roof( below, false );
3433 if( roof == ter( p ) ) {
3434 smash_ter = false;
3435 bash = nullptr;
3436 }
3437 } else if( !bash->ter_set && ter( p ) == t_dirt ) {
3438 // As above, except for no-z-levels case
3439 smash_ter = false;
3440 bash = nullptr;
3441 }
3442 }
3443
3444 // TODO: what if silent is true?
3445 if( has_flag( "ALARMED", p ) && !g->timed_events.queued( TIMED_EVENT_WANTED ) ) {
3446 sounds::sound( p, 40, sounds::sound_t::alarm, _( "an alarm go off!" ),
3447 false, "environment", "alarm" );
3448 // Blame nearby player
3449 if( rl_dist( g->u.pos(), p ) <= 3 ) {
3450 g->events().send<event_type::triggers_alarm>( g->u.getID() );
3451 const point abs = ms_to_sm_copy( getabs( p.xy() ) );
3452 g->timed_events.add( TIMED_EVENT_WANTED, calendar::turn + 30_minutes, 0,
3453 tripoint( abs, p.z ) );
3454 }
3455 }
3456
3457 if( bash == nullptr || ( bash->destroy_only && !params.destroy ) ) {
3458 // Nothing bashable here
3459 if( impassable( p ) ) {
3460 if( !params.silent ) {
3461 sounds::sound( p, 18, sounds::sound_t::combat, _( "thump!" ),
3462 false, "smash_fail", "default" );
3463 }
3464
3465 result.did_bash = true;
3466 result.bashed_solid = true;
3467 }
3468
3469 return result;
3470 }
3471
3472 result.did_bash = true;
3473 result.bashed_solid = true;
3474 result.success = params.destroy;
3475
3476 int smin = bash->str_min;
3477 int smax = bash->str_max;
3478 if( !params.destroy ) {
3479 if( bash->str_min_blocked != -1 || bash->str_max_blocked != -1 ) {
3480 if( furn_is_supported( *this, p ) ) {
3481 if( bash->str_min_blocked != -1 ) {
3482 smin = bash->str_min_blocked;
3483 }
3484 if( bash->str_max_blocked != -1 ) {
3485 smax = bash->str_max_blocked;
3486 }
3487 }
3488 }
3489
3490 if( bash->str_min_supported != -1 || bash->str_max_supported != -1 ) {
3491 tripoint below( p.xy(), p.z - 1 );
3492 if( !zlevels || has_flag( TFLAG_SUPPORTS_ROOF, below ) ) {
3493 if( bash->str_min_supported != -1 ) {
3494 smin = bash->str_min_supported;
3495 }
3496 if( bash->str_max_supported != -1 ) {
3497 smax = bash->str_max_supported;
3498 }
3499 }
3500 }
3501 // Linear interpolation from str_min to str_max
3502 const int resistance = smin + ( params.roll * ( smax - smin ) );
3503 if( params.strength >= resistance ) {
3504 result.success = true;
3505 }
3506 }
3507
3508 if( !result.success ) {
3509 int sound_volume = bash->sound_fail_vol.value_or( 12 );
3510
3511 result.did_bash = true;
3512 if( !params.silent ) {
3513 sounds::sound( p, sound_volume, sounds::sound_t::combat, bash->sound_fail, false,
3514 "smash_fail", soundfxvariant );
3515 }
3516 } else {
3517 if( smash_ter ) {
3518 result |= bash_ter_success( p, params );
3519 } else {
3520 result |= bash_furn_success( p, params );
3521 }
3522 }
3523
3524 return result;
3525}
ter_id get_roof(const tripoint &p, bool allow_air) const
Definition: map.cpp:3105
bash_results bash_furn_success(const tripoint &p, const bash_params &params)
Definition: map.cpp:3303
bash_results bash_ter_success(const tripoint &p, const bash_params &params)
Definition: map.cpp:3173
point ms_to_sm_copy(const point &p)
static bool furn_is_supported(const map &m, const tripoint &p)
Definition: map.cpp:3149
ter_id t_dirt
Definition: mapdata.cpp:625
@ TFLAG_SUPPORTS_ROOF
Definition: mapdata.h:280
float roll
Value from 0.0 to 1.0 that affects interpolation between str_min and str_max At 0....
Definition: map.h:147
bool bash_floor
Definition: map.h:140
bool destroy
Definition: map.h:138
int strength
Definition: map.h:134
@ TIMED_EVENT_WANTED
Definition: timed_event.h:13

References _, sounds::alarm, bash(), bash_params::bash_floor, bash_furn_success(), bash_ter_success(), sounds::combat, bash_params::destroy, furn(), furn_is_supported(), g, get_roof(), getabs(), has_flag(), impassable(), ms_to_sm_copy(), int_id< T >::obj(), rl_dist(), bash_params::roll, bash_params::silent, sounds::sound(), bash_params::strength, t_dirt, ter(), TFLAG_SUPPORTS_ROOF, TIMED_EVENT_WANTED, triggers_alarm, calendar::turn, tripoint::xy(), tripoint::z, and zlevels.

Referenced by bash(), bash_ter_success(), and explosion_handler::do_blast_new().

◆ bash_ter_success()

bash_results map::bash_ter_success ( const tripoint p,
const bash_params params 
)

Definition at line 3173 of file map.cpp.

3174{
3176 result.success = true;
3177 const ter_t &ter_before = ter( p ).obj();
3178 const map_bash_info &bash = ter_before.bash;
3179 if( has_flag_ter( "FUNGUS", p ) ) {
3180 fungal_effects( *g, *this ).create_spores( p );
3181 }
3182 const std::string soundfxvariant = ter_before.id.str();
3183 const bool will_collapse = ter_before.has_flag( TFLAG_SUPPORTS_ROOF ) &&
3184 !ter_before.has_flag( TFLAG_INDOORS );
3185 const bool suspended = ter_before.has_flag( TFLAG_SUSPENDED );
3186 bool follow_below = false;
3187 if( params.bashing_from_above && bash.ter_set_bashed_from_above ) {
3188 // If this terrain is being bashed from above and this terrain
3189 // has a valid post-destroy bashed-from-above terrain, set it
3190 ter_set( p, bash.ter_set_bashed_from_above );
3191 } else if( bash.ter_set ) {
3192 // If the terrain has a valid post-destroy terrain, set it
3193 ter_set( p, bash.ter_set );
3194 follow_below |= zlevels && bash.bash_below;
3195 } else if( suspended ) {
3196 // Its important that we change the ter value before recursing, otherwise we'll hit an infinite loop.
3197 // This could be prevented by assembling a visited list, but in order to avoid that cost, we're going
3198 // build our recursion to just be resilient.
3199 ter_set( p, t_open_air );
3201 } else {
3202 tripoint below( p.xy(), p.z - 1 );
3203 const ter_t &ter_below = ter( below ).obj();
3204 // Only setting the flag here because we want drops and sounds in correct order
3205 follow_below |= zlevels && bash.bash_below && ter_below.roof;
3206
3207 ter_set( p, t_open_air );
3208 }
3209
3211
3212 if( !bash.sound.empty() && !params.silent ) {
3213 static const std::string soundfxid = "smash_success";
3214 int sound_volume = get_sound_volume( bash );
3215 sounds::sound( p, sound_volume, sounds::sound_t::combat, bash.sound, false,
3216 soundfxid, soundfxvariant );
3217 }
3218
3219 if( !zlevels ) {
3220 if( ter( p ) == t_open_air ) {
3221 // We destroyed something, so we aren't just "plugging" air with dirt here
3222 ter_set( p, t_dirt );
3223 }
3224 } else if( follow_below || ter( p ) == t_open_air ) {
3225 const tripoint below( p.xy(), p.z - 1 );
3226 // We may need multiple bashes in some weird cases
3227 // Example:
3228 // W has roof A
3229 // A bashes to B
3230 // B bashes to nothing
3231 // Below our point P, there is a W
3232 // If we bash down a B over a W, it might be from earlier A or just constructed over it!
3233 //
3234 // Current solution: bash roof until you reach same roof type twice, then bash down
3235 if( follow_below && params.do_recurse ) {
3236 bool blocked_by_roof = false;
3237 std::set<ter_id> encountered_types;
3238 encountered_types.insert( ter_before.id );
3239 encountered_types.insert( t_open_air );
3240 // Note: we're bashing the new roof, not the tile supported by it!
3241 int down_bash_tries = 10;
3242 do {
3243 const ter_id &ter_now = ter( p );
3244 if( encountered_types.count( ter_now ) != 0 ) {
3245 // We have encountered this type before and destroyed it (didn't block us)
3246 ter_set( p, t_open_air );
3247 bash_params params_below = params;
3248 params_below.bashing_from_above = true;
3249 params_below.bash_floor = false;
3250 params_below.do_recurse = false;
3251 params_below.destroy = true;
3252 int impassable_bash_tries = 10;
3253 // Unconditionally destroy, but don't go deeper
3254 do {
3255 result |= bash_ter_success( below, params_below );
3256 } while( ter( below )->movecost == 0 && impassable_bash_tries-- > 0 );
3257 if( impassable_bash_tries <= 0 ) {
3258 debugmsg( "Loop in terrain bashing for type %s", ter_before.id.str() );
3259 }
3260 } else if( ter_now == t_open_air ) {
3261 const ter_id &roof = get_roof( below, params.bash_floor && ter( below )->movecost != 0 );
3262 if( roof != t_open_air ) {
3263 ter_set( p, roof );
3264 }
3265 } else {
3266 // This floor/roof tile wasn't destroyed in this loop yet
3267 encountered_types.insert( ter_now );
3268 bash_params params_copy = params;
3269 params_copy.do_recurse = false;
3270 // TODO: Unwrap the calls, don't recurse
3271 // TODO: Don't bash furn
3272 bash_results results_sub = bash_ter_furn( p, params_copy );
3273 result |= results_sub;
3274 if( !results_sub.success ) {
3275 // Blocked, as in "the roof was too strong to bash"
3276 blocked_by_roof = true;
3277 }
3278 }
3279 } while( down_bash_tries-- > 0 && !blocked_by_roof &&
3280 ( ter( p ) != t_open_air || ter( p )->movecost == 0 || ter( below )->roof ) );
3281 if( down_bash_tries <= 0 ) {
3282 debugmsg( "Loop in terrain bashing for type %s", ter_before.id.str() );
3283 }
3284 } else {
3285 const ter_id &roof = get_roof( below, params.bash_floor && ter( below )->movecost != 0 );
3286
3287 ter_set( p, roof );
3288 }
3289 }
3290
3291 if( will_collapse && !has_flag( TFLAG_SUPPORTS_ROOF, p ) ) {
3292 collapse_at( p, params.silent, true, bash.explosive > 0 );
3293 }
3294
3295 if( bash.explosive > 0 ) {
3296 // TODO Implement if the player triggered the explosive terrain
3297 explosion_handler::explosion( p, nullptr, bash.explosive, 0.8, false );
3298 }
3299
3300 return result;
3301}
void propagate_suspension_check(const tripoint &point)
Checks surrounding tiles for suspension, and has them check for collapse.
Definition: map.cpp:2954
void collapse_at(const tripoint &p, bool silent, bool was_supporting=false, bool destroy_pos=true)
Causes a collapse at p, such as from destroying a wall.
Definition: map.cpp:2909
const std::string & str() const
Returns the identifier as plain std::string.
Definition: string_id.h:255
@ TFLAG_SUSPENDED
Definition: mapdata.h:323
@ TFLAG_INDOORS
Definition: mapdata.h:291
bool do_recurse
Hack to prevent infinite recursion.
Definition: map.h:159
bool bashing_from_above
Definition: map.h:154
bool success
Definition: map.h:170
bool has_flag(const std::string &flag) const
Definition: mapdata.h:415
ter_str_id id
Definition: mapdata.h:461

References bash(), map_data_common_t::bash, bash_params::bash_floor, bash_ter_furn(), bash_ter_success(), bash_params::bashing_from_above, collapse_at(), sounds::combat, fungal_effects::create_spores(), debugmsg, bash_params::destroy, bash_params::do_recurse, explosion_handler::explosion(), g, get_roof(), get_sound_volume(), map_data_common_t::has_flag(), has_flag(), has_flag_ter(), ter_t::id, item_group::items_from(), int_id< T >::obj(), propagate_suspension_check(), ter_t::roof, bash_params::silent, sounds::sound(), spawn_items(), string_id< T >::str(), bash_results::success, t_dirt, t_open_air, ter(), ter_set(), TFLAG_INDOORS, TFLAG_SUPPORTS_ROOF, TFLAG_SUSPENDED, calendar::turn, tripoint::xy(), tripoint::z, and zlevels.

Referenced by bash_ter_furn(), bash_ter_success(), and shoot().

◆ bash_vehicle()

bash_results map::bash_vehicle ( const tripoint p,
const bash_params params 
)

Definition at line 3599 of file map.cpp.

3600{
3602 // Smash vehicle if present
3603 if( const optional_vpart_position vp = veh_at( p ) ) {
3604 vp->vehicle().damage( vp->part_index(), params.strength, DT_BASH );
3605 if( !params.silent ) {
3606 sounds::sound( p, 18, sounds::sound_t::combat, _( "crash!" ), false,
3607 "smash_success", "hit_vehicle" );
3608 }
3609
3610 result.did_bash = true;
3611 result.success = true;
3612 result.bashed_solid = true;
3613 }
3614 return result;
3615}
@ DT_BASH
Definition: damage.h:24

References _, sounds::combat, DT_BASH, bash_params::silent, sounds::sound(), bash_params::strength, and veh_at().

Referenced by bash().

◆ batter()

void map::batter ( const tripoint p,
int  power,
int  tries = 1,
bool  silent = false 
)

bash a square for a set number of times at set power.

Does not destroy

Definition at line 3664 of file map.cpp.

3665{
3666 int count = 0;
3667 while( count < tries && bash( p, power, silent ).success ) {
3668 count++;
3669 }
3670}
@ success
Definition: behavior.h:20

References bash(), detail::count(), silent, and behavior::success.

Referenced by activity_handlers::chop_tree_finish().

◆ board_vehicle()

void map::board_vehicle ( const tripoint p,
player pl 
)

Definition at line 1049 of file map.cpp.

1050{
1051 if( p == nullptr ) {
1052 debugmsg( "map::board_vehicle: null player" );
1053 return;
1054 }
1055
1057 true );
1058 if( !vp ) {
1059 if( p->grab_point.x == 0 && p->grab_point.y == 0 ) {
1060 debugmsg( "map::board_vehicle: vehicle not found" );
1061 }
1062 return;
1063 }
1064 if( vp->part().has_flag( vehicle_part::passenger_flag ) ) {
1065 player *psg = vp->vehicle().get_passenger( vp->part_index() );
1066 debugmsg( "map::board_vehicle: passenger (%s) is already there",
1067 psg ? psg->name : "<null>" );
1068 unboard_vehicle( pos );
1069 }
1070 vp->part().set_flag( vehicle_part::passenger_flag );
1071 vp->part().passenger_id = p->getID();
1072 vp->vehicle().invalidate_mass();
1073
1074 p->setpos( pos );
1075 p->in_vehicle = true;
1076 if( p->is_avatar() ) {
1077 g->update_map( g->u );
1078 }
1079}
std::string name
Definition: character.h:1504
void unboard_vehicle(const vpart_reference &, Character *passenger, bool dead_passenger=false)
Definition: map.cpp:1081
cata::optional< vpart_reference > part_with_feature(const std::string &f, bool unbroken) const
Definition: vehicle.cpp:2481
Definition: player.h:91
@ passenger_flag
Definition: vehicle.h:192
@ VPFLAG_BOARDABLE
Definition: veh_type.h:39

References debugmsg, g, Character::getID(), player::grab_point, Character::in_vehicle, Creature::is_avatar(), Character::name, optional_vpart_position::part_with_feature(), vehicle_part::passenger_flag, wrapped_vehicle::pos, Character::setpos(), unboard_vehicle(), veh_at(), VPFLAG_BOARDABLE, tripoint::x, and tripoint::y.

Referenced by debug_menu::debug(), npc::move_to(), game::phasing_move(), game::place_player(), game::swap_critters(), and avatar_action::swim().

◆ build_floor_cache()

bool map::build_floor_cache ( int  zlev)

Definition at line 8014 of file map.cpp.

8015{
8016 auto &ch = get_cache( zlev );
8017 if( !ch.floor_cache_dirty ) {
8018 return false;
8019 }
8020
8021 auto &floor_cache = ch.floor_cache;
8022 std::uninitialized_fill_n(
8023 &floor_cache[0][0], ( MAPSIZE_X ) * ( MAPSIZE_Y ), true );
8024
8025 bool lowest_z_lev = zlev <= -OVERMAP_DEPTH;
8026 for( int smx = 0; smx < my_MAPSIZE; ++smx ) {
8027 for( int smy = 0; smy < my_MAPSIZE; ++smy ) {
8028 const submap *cur_submap = get_submap_at_grid( { smx, smy, zlev } );
8029 const submap *below_submap = !lowest_z_lev ? get_submap_at_grid( { smx, smy, zlev - 1 } ) : nullptr;
8030
8031 if( cur_submap == nullptr ) {
8032 debugmsg( "Tried to build floor cache at (%d,%d,%d) but the submap is not loaded", smx, smy, zlev );
8033 continue;
8034 }
8035 if( !lowest_z_lev && below_submap == nullptr ) {
8036 debugmsg( "Tried to build floor cache at (%d,%d,%d) but the submap is not loaded", smx, smy,
8037 zlev - 1 );
8038 continue;
8039 }
8040
8041 for( int sx = 0; sx < SEEX; ++sx ) {
8042 for( int sy = 0; sy < SEEY; ++sy ) {
8043 point sp( sx, sy );
8044 const ter_t &terrain = cur_submap->get_ter( sp ).obj();
8045 if( terrain.has_flag( TFLAG_NO_FLOOR ) ) {
8046 if( below_submap && ( below_submap->get_furn( sp ).obj().has_flag( TFLAG_SUN_ROOF_ABOVE ) ) ) {
8047 continue;
8048 }
8049 const int x = sx + smx * SEEX;
8050 const int y = sy + smy * SEEY;
8051 floor_cache[x][y] = false;
8052 }
8053 }
8054 }
8055 }
8056 }
8057
8058 ch.floor_cache_dirty = false;
8059 return zlevels;
8060}
@ TFLAG_SUN_ROOF_ABOVE
Definition: mapdata.h:322
@ TFLAG_NO_FLOOR
Definition: mapdata.h:310
static const int sx[4]
Definition: tileray.cpp:10
static const int sy[4]
Definition: tileray.cpp:11

References debugmsg, get_cache(), get_submap_at_grid(), submap::get_ter(), MAPSIZE_X, MAPSIZE_Y, my_MAPSIZE, int_id< T >::obj(), OVERMAP_DEPTH, SEEX, SEEY, sx, sy, terrain, TFLAG_NO_FLOOR, TFLAG_SUN_ROOF_ABOVE, and zlevels.

Referenced by build_floor_caches(), and build_map_cache().

◆ build_floor_caches()

void map::build_floor_caches ( )

Definition at line 8062 of file map.cpp.

8063{
8064 const int minz = zlevels ? -OVERMAP_DEPTH : abs_sub.z;
8065 const int maxz = zlevels ? OVERMAP_HEIGHT : abs_sub.z;
8066 for( int z = minz; z <= maxz; z++ ) {
8067 build_floor_cache( z );
8068 }
8069}
bool build_floor_cache(int zlev)
Definition: map.cpp:8014

References abs_sub, build_floor_cache(), OVERMAP_DEPTH, OVERMAP_HEIGHT, tripoint::z, and zlevels.

Referenced by game::do_turn().

◆ build_map_cache()

void map::build_map_cache ( int  zlev,
bool  skip_lightmap = false 
)

Definition at line 8228 of file map.cpp.

8229{
8230 const int minz = zlevels ? -OVERMAP_DEPTH : zlev;
8231 const int maxz = zlevels ? OVERMAP_HEIGHT : zlev;
8232 bool seen_cache_dirty = false;
8233 for( int z = minz; z <= maxz; z++ ) {
8234 // trigger FOV recalculation only when there is a change on the player's level or if fov_3d is enabled
8235 const bool affects_seen_cache = z == zlev || fov_3d;
8239 seen_cache_dirty |= ( build_floor_cache( z ) && affects_seen_cache );
8240 seen_cache_dirty |= get_cache( z ).seen_cache_dirty && affects_seen_cache;
8241 diagonal_blocks fill = {false, false};
8242 std::uninitialized_fill_n( &( get_cache( z ).vehicle_obscured_cache[0][0] ), MAPSIZE_X * MAPSIZE_Y,
8243 fill );
8244 std::uninitialized_fill_n( &( get_cache( z ).vehicle_obstructed_cache[0][0] ),
8246 }
8247 // needs a separate pass as it changes the caches on neighbour z-levels (e.g. floor_cache);
8248 // otherwise such changes might be overwritten by main cache-building logic
8249 for( int z = minz; z <= maxz; z++ ) {
8250 do_vehicle_caching( z );
8251 }
8252
8254
8255 if( seen_cache_dirty ) {
8256 skew_vision_cache.clear();
8257 }
8258 // Initial value is illegal player position.
8259 const tripoint &p = g->u.pos();
8260 static tripoint player_prev_pos;
8261 if( seen_cache_dirty || player_prev_pos != p ) {
8262 build_seen_cache( p, zlev );
8263 player_prev_pos = p;
8264 }
8265 if( !skip_lightmap ) {
8266 generate_lightmap( zlev );
8267 }
8268}
bool fov_3d
3D FoV enabled/disabled.
void build_outside_cache(int zlev)
Definition: map.cpp:7907
void update_suspension_cache(const int &z)
Definition: map.cpp:8071
void do_vehicle_caching(int z)
Definition: map.cpp:8211
void build_seen_cache(const tripoint &origin, int target_z)
Calculates the Field Of View for the provided map from the given x, y coordinates.
Definition: lightmap.cpp:1392
lru_cache< point, char > skew_vision_cache
Cache of coordinate pairs recently checked for visibility.
Definition: map.h:2027
bool build_transparency_cache(int zlev)
Definition: lightmap.cpp:82
void generate_lightmap(int zlev)
Definition: lightmap.cpp:400
bool build_vision_transparency_cache(const Character &player)
Definition: lightmap.cpp:168
FMT_NOINLINE OutputIt fill(OutputIt it, size_t n, const fill_t< Char > &fill)
bool seen_cache_dirty
Definition: map.h:309

References build_floor_cache(), build_outside_cache(), build_seen_cache(), build_transparency_cache(), build_vision_transparency_cache(), do_vehicle_caching(), detail::fill(), fov_3d, g, generate_lightmap(), get_cache(), get_player_character(), MAPSIZE_X, MAPSIZE_Y, OVERMAP_DEPTH, OVERMAP_HEIGHT, level_cache::seen_cache_dirty, skew_vision_cache, update_suspension_cache(), and zlevels.

Referenced by game::do_turn(), game::draw(), game::look_around(), start_location::place_player(), game::start_game(), and game::update_map().

◆ build_obstacle_cache()

void map::build_obstacle_cache ( const tripoint start,
const tripoint end,
float(&)  obstacle_cache[MAPSIZE_X][MAPSIZE_Y] 
)

Definition at line 7961 of file map.cpp.

7963{
7964 const point min_submap{ std::max( 0, start.x / SEEX ), std::max( 0, start.y / SEEY ) };
7965 const point max_submap{
7966 std::min( my_MAPSIZE - 1, end.x / SEEX ), std::min( my_MAPSIZE - 1, end.y / SEEY ) };
7967 // Find and cache all the map obstacles.
7968 // For now setting obstacles to be extremely dense and fill their squares.
7969 // In future, scale effective obstacle density by the thickness of the obstacle.
7970 // Also consider modelling partial obstacles.
7971 // TODO: Support z-levels.
7972 for( int smx = min_submap.x; smx <= max_submap.x; ++smx ) {
7973 for( int smy = min_submap.y; smy <= max_submap.y; ++smy ) {
7974 const auto cur_submap = get_submap_at_grid( { smx, smy, start.z } );
7975
7976 // TODO: Init indices to prevent iterating over unused submap sections.
7977 for( int sx = 0; sx < SEEX; ++sx ) {
7978 for( int sy = 0; sy < SEEY; ++sy ) {
7979 const point sp( sx, sy );
7980 int ter_move = cur_submap->get_ter( sp ).obj().movecost;
7981 int furn_move = cur_submap->get_furn( sp ).obj().movecost;
7982 const int x = sx + smx * SEEX;
7983 const int y = sy + smy * SEEY;
7984 if( ter_move == 0 || furn_move < 0 || ter_move + furn_move == 0 ) {
7985 obstacle_cache[x][y] = 1000.0f;
7986 } else {
7987 obstacle_cache[x][y] = 0.0f;
7988 }
7989 }
7990 }
7991 }
7992 }
7993 VehicleList vehs = get_vehicles( start, end );
7994 const inclusive_cuboid<tripoint> bounds( start, end );
7995 // Cache all the vehicle stuff in one loop
7996 for( auto &v : vehs ) {
7997 for( const vpart_reference &vp : v.v->get_all_parts() ) {
7998 tripoint p = v.pos + vp.part().precalc[0];
7999 if( p.z != start.z ) {
8000 break;
8001 }
8002 if( !bounds.contains( p ) ) {
8003 continue;
8004 }
8005
8006 if( vp.obstacle_at_part() ) {
8007 obstacle_cache[p.x][p.y] = 1000.0f;
8008 }
8009 }
8010 }
8011
8012}
VehicleList get_vehicles()
Definition: map.cpp:237
std::vector< wrapped_vehicle > VehicleList
Definition: map.h:85

References inclusive_cuboid< Tripoint, >::contains(), get_submap_at_grid(), get_vehicles(), my_MAPSIZE, SEEX, SEEY, sx, sy, tripoint::x, tripoint::y, and tripoint::z.

Referenced by explosion_handler::shrapnel().

◆ build_outside_cache()

void map::build_outside_cache ( int  zlev)

Definition at line 7907 of file map.cpp.

7908{
7909 auto &ch = get_cache( zlev );
7910 if( !ch.outside_cache_dirty ) {
7911 return;
7912 }
7913
7914 // Make a bigger cache to avoid bounds checking
7915 // We will later copy it to our regular cache
7916 const size_t padded_w = ( MAPSIZE_X ) + 2;
7917 const size_t padded_h = ( MAPSIZE_Y ) + 2;
7918 bool padded_cache[padded_w][padded_h];
7919
7920 auto &outside_cache = ch.outside_cache;
7921 if( zlev < 0 ) {
7922 std::uninitialized_fill_n(
7923 &outside_cache[0][0], ( MAPSIZE_X ) * ( MAPSIZE_Y ), false );
7924 return;
7925 }
7926
7927 std::uninitialized_fill_n(
7928 &padded_cache[0][0], padded_w * padded_h, true );
7929
7930 for( int smx = 0; smx < my_MAPSIZE; ++smx ) {
7931 for( int smy = 0; smy < my_MAPSIZE; ++smy ) {
7932 const auto cur_submap = get_submap_at_grid( { smx, smy, zlev } );
7933
7934 for( int sx = 0; sx < SEEX; ++sx ) {
7935 for( int sy = 0; sy < SEEY; ++sy ) {
7936 point sp( sx, sy );
7937 if( cur_submap->get_ter( sp ).obj().has_flag( TFLAG_INDOORS ) ||
7938 cur_submap->get_furn( sp ).obj().has_flag( TFLAG_INDOORS ) ) {
7939 const int x = sx + smx * SEEX;
7940 const int y = sy + smy * SEEY;
7941 // Add 1 to both coordinates, because we're operating on the padded cache
7942 for( int dx = 0; dx <= 2; dx++ ) {
7943 for( int dy = 0; dy <= 2; dy++ ) {
7944 padded_cache[x + dx][y + dy] = false;
7945 }
7946 }
7947 }
7948 }
7949 }
7950 }
7951 }
7952
7953 // Copy the padded cache back to the proper one, but with no padding
7954 for( int x = 0; x < SEEX * my_MAPSIZE; x++ ) {
7955 std::copy_n( &padded_cache[x + 1][1], SEEX * my_MAPSIZE, &outside_cache[x][0] );
7956 }
7957
7958 ch.outside_cache_dirty = false;
7959}

References get_cache(), get_submap_at_grid(), MAPSIZE_X, MAPSIZE_Y, my_MAPSIZE, SEEX, SEEY, sx, sy, and TFLAG_INDOORS.

Referenced by build_map_cache(), start_location::burn(), and start_location::prepare_map().

◆ build_seen_cache()

void map::build_seen_cache ( const tripoint origin,
int  target_z 
)
protected

Calculates the Field Of View for the provided map from the given x, y coordinates.

Returns a lightmap for a result where the values represent a percentage of fully lit.

A value equal to or below 0 means that cell is not in the field of view, whereas a value equal to or above 1 means that cell is in the field of view.

Parameters
originthe starting location
target_zZ-level to draw light map on

Definition at line 1392 of file lightmap.cpp.

1393{
1394 auto &map_cache = get_cache( target_z );
1395 float ( &transparency_cache )[MAPSIZE_X][MAPSIZE_Y] = map_cache.transparency_cache;
1396 float ( &seen_cache )[MAPSIZE_X][MAPSIZE_Y] = map_cache.seen_cache;
1397 float ( &camera_cache )[MAPSIZE_X][MAPSIZE_Y] = map_cache.camera_cache;
1398 diagonal_blocks( &blocked_cache )[MAPSIZE_X][MAPSIZE_Y] = map_cache.vehicle_obscured_cache;
1399
1400 constexpr float light_transparency_solid = LIGHT_TRANSPARENCY_SOLID;
1401 constexpr int map_dimensions = MAPSIZE_X * MAPSIZE_Y;
1402 std::uninitialized_fill_n(
1403 &camera_cache[0][0], map_dimensions, light_transparency_solid );
1404
1405 float vision_restore_cache [9] = {0};
1406 bool blocked_restore_cache[8] = {false};
1407
1408 if( origin.z == target_z ) {
1409 apply_vision_transparency_cache( get_player_character().pos(), target_z, vision_restore_cache,
1410 blocked_restore_cache );
1411 }
1412
1413 if( !fov_3d ) {
1414 for( int z = -OVERMAP_DEPTH; z <= OVERMAP_HEIGHT; z++ ) {
1415 auto &cur_cache = get_cache( z );
1416 if( z == target_z || cur_cache.seen_cache_dirty ) {
1417 std::uninitialized_fill_n(
1418 &cur_cache.seen_cache[0][0], map_dimensions, light_transparency_solid );
1419 cur_cache.seen_cache_dirty = false;
1420 }
1421
1422 if( z == target_z ) {
1423 seen_cache[origin.x][origin.y] = VISIBILITY_FULL;
1424 castLightAll<float, float, sight_calc, sight_check, update_light, accumulate_transparency>(
1425 seen_cache, transparency_cache, blocked_cache, origin.xy(), 0 );
1426 }
1427 }
1428 } else {
1429 // Cache the caches (pointers to them)
1430 array_of_grids_of<const float> transparency_caches;
1431 array_of_grids_of<float> seen_caches;
1432 array_of_grids_of<const bool> floor_caches;
1434 for( int z = -OVERMAP_DEPTH; z <= OVERMAP_HEIGHT; z++ ) {
1435 auto &cur_cache = get_cache( z );
1436 transparency_caches[z + OVERMAP_DEPTH] = &cur_cache.transparency_cache;
1437 seen_caches[z + OVERMAP_DEPTH] = &cur_cache.seen_cache;
1438 floor_caches[z + OVERMAP_DEPTH] = &cur_cache.floor_cache;
1439 blocked_caches[z + OVERMAP_DEPTH] = &cur_cache.vehicle_obscured_cache;
1440 std::uninitialized_fill_n(
1441 &cur_cache.seen_cache[0][0], map_dimensions, light_transparency_solid );
1442 cur_cache.seen_cache_dirty = false;
1443 }
1444 if( origin.z == target_z ) {
1446 }
1448 seen_caches, transparency_caches, floor_caches, blocked_caches, origin, 0, 1.0 );
1449 }
1450
1451 if( origin.z == target_z ) {
1452 restore_vision_transparency_cache( get_player_character().pos(), target_z, vision_restore_cache,
1453 blocked_restore_cache );
1454 }
1455
1457 if( !vp ) {
1458 return;
1459 }
1460 vehicle *const veh = &vp->vehicle();
1461
1462 // We're inside a vehicle. Do mirror calculations.
1463 std::vector<int> mirrors;
1464 // Do all the sight checks first to prevent fake multiple reflection
1465 // from happening due to mirrors becoming visible due to processing order.
1466 // Cameras are also handled here, so that we only need to get through all vehicle parts once
1467 int cam_control = -1;
1468 for( const vpart_reference &vp : veh->get_avail_parts( VPFLAG_EXTENDS_VISION ) ) {
1469 const tripoint mirror_pos = vp.pos();
1470 // We can utilize the current state of the seen cache to determine
1471 // if the player can see the mirror from their position.
1472 if( !vp.info().has_flag( "CAMERA" ) &&
1473 seen_cache[mirror_pos.x][mirror_pos.y] < LIGHT_TRANSPARENCY_SOLID + 0.1 ) {
1474 continue;
1475 } else if( !vp.info().has_flag( "CAMERA_CONTROL" ) ) {
1476 mirrors.emplace_back( static_cast<int>( vp.part_index() ) );
1477 } else {
1478 if( square_dist( origin, mirror_pos ) <= 1 && veh->camera_on ) {
1479 cam_control = static_cast<int>( vp.part_index() );
1480 }
1481 }
1482 }
1483
1484 for( int mirror : mirrors ) {
1485 bool is_camera = veh->part_info( mirror ).has_flag( "CAMERA" );
1486 if( is_camera && cam_control < 0 ) {
1487 continue; // Player not at camera control, so cameras don't work
1488 }
1489
1490 const tripoint mirror_pos = veh->global_part_pos3( mirror );
1491
1492 // Determine how far the light has already traveled so mirrors
1493 // don't cheat the light distance falloff.
1494 int offsetDistance;
1495 if( !is_camera ) {
1496 offsetDistance = rl_dist( origin, mirror_pos );
1497 } else {
1498 offsetDistance = 60 - veh->part_info( mirror ).bonus *
1499 veh->part( mirror ).hp() / veh->part_info( mirror ).durability;
1500 camera_cache[mirror_pos.x][mirror_pos.y] = LIGHT_TRANSPARENCY_OPEN_AIR;
1501 }
1502
1503 // TODO: Factor in the mirror facing and only cast in the
1504 // directions the player's line of sight reflects to.
1505 //
1506 // The naive solution of making the mirrors act like a second player
1507 // at an offset appears to give reasonable results though.
1508 castLightAll<float, float, sight_calc, sight_check, update_light, accumulate_transparency>(
1509 camera_cache, transparency_cache, blocked_cache, mirror_pos.xy(), offsetDistance );
1510 }
1511}
void restore_vision_transparency_cache(const tripoint &center, int target_z, float(&vision_restore_cache)[9], bool(&blocked_restore_cache)[8])
Definition: lightmap.cpp:1352
void apply_vision_transparency_cache(const tripoint &center, int target_z, float(&vision_restore_cache)[9], bool(&blocked_restore_cache)[8])
Definition: lightmap.cpp:1313
vehicle_part_with_feature_range< std::string > get_avail_parts(std::string feature) const
Yields a range of parts of this vehicle that each have the given feature and are available: not broke...
Definition: vehicle.cpp:2714
bool camera_on
Definition: vehicle.h:1996
const vpart_info & part_info(int index, bool include_removed=false) const
Definition: vehicle.cpp:1137
int bonus
seatbelt (str), muffler (%), horn (vol), light (intensity), recharing (power)
Definition: veh_type.h:269
bool has_flag(const std::string &flag) const
Definition: veh_type.h:336
int durability
Maximum damage part can sustain before being destroyed.
Definition: veh_type.h:173
template void cast_zlight< float, sight_calc, sight_check, accumulate_transparency >(const array_of_grids_of< float > &output_caches, const array_of_grids_of< const float > &input_arrays, const array_of_grids_of< const bool > &floor_caches, const array_of_grids_of< const diagonal_blocks > &blocked_caches, const tripoint &origin, int offset_distance, float numerator)
static constexpr float VISIBILITY_FULL
Definition: lightmap.h:39
std::array< T(*)[MAPSIZE_X][MAPSIZE_Y], OVERMAP_LAYERS > array_of_grids_of
int hp() const
current part health with range [0,durability]
@ VPFLAG_EXTENDS_VISION
Definition: veh_type.h:68

References apply_vision_transparency_cache(), vpart_info::bonus, vehicle::camera_on, cast_zlight< float, sight_calc, sight_check, accumulate_transparency >(), vpart_info::durability, fov_3d, vehicle::get_avail_parts(), get_cache(), get_player_character(), vehicle::global_part_pos3(), vpart_info::has_flag(), vehicle_part::hp(), LIGHT_TRANSPARENCY_OPEN_AIR, LIGHT_TRANSPARENCY_SOLID, MAPSIZE_X, MAPSIZE_Y, OVERMAP_DEPTH, OVERMAP_HEIGHT, vehicle::part(), vehicle::part_info(), restore_vision_transparency_cache(), rl_dist(), level_cache::seen_cache, square_dist(), veh_at(), VISIBILITY_FULL, VPFLAG_EXTENDS_VISION, tripoint::x, tripoint::xy(), and tripoint::y.

Referenced by build_map_cache().

◆ build_sunlight_cache()

void map::build_sunlight_cache ( int  pzlev)
protected

Definition at line 249 of file lightmap.cpp.

250{
251 const int zlev_min = zlevels ? -OVERMAP_DEPTH : pzlev;
252 // Start at the topmost populated zlevel to avoid unnecessary raycasting
253 // Plus one zlevel to prevent clipping inside structures
254 const int zlev_max = zlevels
256 std::min( OVERMAP_HEIGHT, pzlev + 1 ),
258 : pzlev;
259
260 // true if all previous z-levels are fully transparent to light (no floors, transparency >= air)
261 bool fully_outside = true;
262
263 // true if no light reaches this level, i.e. there were no lit tiles on the above level (light level <= inside_light_level)
264 bool fully_inside = false;
265
266 // fully_outside and fully_inside define following states:
267 // initially: fully_outside=true, fully_inside=false (fast fill)
268 // ↓
269 // when first obstacles occur: fully_outside=false, fully_inside=false (slow quadrant logic)
270 // ↓
271 // when fully below ground: fully_outside=false, fully_inside=true (fast fill)
272
273 // Iterate top to bottom because sunlight cache needs to construct in that order.
274 for( int zlev = zlev_max; zlev >= zlev_min; zlev-- ) {
275
276 level_cache &map_cache = get_cache( zlev );
277 auto &lm = map_cache.lm;
278 // Grab illumination at ground level.
279 const float outside_light_level = g->natural_light_level( 0 );
280 // TODO: if zlev < 0 is open to sunlight, this won't calculate correct light, but neither does g->natural_light_level()
281 const float inside_light_level = ( zlev >= 0 && outside_light_level > LIGHT_SOURCE_BRIGHT ) ?
283 // Handling when z-levels are disabled is based on whether a tile is considered "outside".
284 if( !zlevels ) {
285 const auto &outside_cache = map_cache.outside_cache;
286 for( int x = 0; x < MAPSIZE_X; x++ ) {
287 for( int y = 0; y < MAPSIZE_Y; y++ ) {
288 if( outside_cache[x][y] ) {
289 lm[x][y].fill( outside_light_level );
290 } else {
291 lm[x][y].fill( inside_light_level );
292 }
293 }
294 }
295 continue;
296 }
297
298 // all light was blocked before
299 if( fully_inside ) {
300 std::fill_n( &lm[0][0], MAPSIZE_X * MAPSIZE_Y, four_quadrants( inside_light_level ) );
301 continue;
302 }
303
304 // If there were no obstacles before this level, just apply weather illumination since there's no opportunity
305 // for light to be blocked.
306 if( fully_outside ) {
307 //fill with full light
308 std::fill_n( &lm[0][0], MAPSIZE_X * MAPSIZE_Y, four_quadrants( outside_light_level ) );
309
310 const auto &this_floor_cache = map_cache.floor_cache;
311 const auto &this_transparency_cache = map_cache.transparency_cache;
312 fully_inside = true; // recalculate
313
314 for( int x = 0; x < MAPSIZE_X; ++x ) {
315 for( int y = 0; y < MAPSIZE_Y; ++y ) {
316 // && semantics below is important, we want to skip the evaluation if possible, do not replace with &=
317
318 // fully_outside stays true if tile is transparent and there is no floor
319 fully_outside = fully_outside && this_transparency_cache[x][y] >= LIGHT_TRANSPARENCY_OPEN_AIR
320 && !this_floor_cache[x][y];
321 // fully_inside stays true if tile is opaque OR there is floor
322 fully_inside = fully_inside && ( this_transparency_cache[x][y] <= LIGHT_TRANSPARENCY_SOLID ||
323 this_floor_cache[x][y] );
324 }
325 }
326 continue;
327 }
328
329 // Replace this with a calculated shift based on time of day and date.
330 // At first compress the angle such that it takes no more than one tile of shift per level.
331 // To exceed that, we'll have to handle casting light from the side instead of the top.
332 point offset;
333 const level_cache &prev_map_cache = get_cache_ref( zlev + 1 );
334 const auto &prev_lm = prev_map_cache.lm;
335 const auto &prev_transparency_cache = prev_map_cache.transparency_cache;
336 const auto &prev_floor_cache = prev_map_cache.floor_cache;
337 const auto &outside_cache = map_cache.outside_cache;
338 const float sight_penalty = get_weather().weather_id->sight_penalty;
339 // TODO: Replace these with a lookup inside the four_quadrants class.
340 constexpr std::array<point, 5> cardinals = {
342 };
343 constexpr std::array<std::array<quadrant, 2>, 5> dir_quadrants = {{
349 }
350 };
351
352 fully_inside = true; // recalculate
353
354 // Fall back to minimal light level if we don't find anything.
355 std::fill_n( &lm[0][0], MAPSIZE_X * MAPSIZE_Y, four_quadrants( inside_light_level ) );
356
357 for( int x = 0; x < MAPSIZE_X; ++x ) {
358 for( int y = 0; y < MAPSIZE_Y; ++y ) {
359 // Check center, then four adjacent cardinals.
360 for( int i = 0; i < 5; ++i ) {
361 int prev_x = x + offset.x + cardinals[i].x;
362 int prev_y = y + offset.y + cardinals[i].y;
363 bool inbounds = prev_x >= 0 && prev_x < MAPSIZE_X &&
364 prev_y >= 0 && prev_y < MAPSIZE_Y;
365
366 if( !inbounds ) {
367 continue;
368 }
369
370 float prev_light_max;
371 float prev_transparency = prev_transparency_cache[prev_x][prev_y];
372 // This is pretty gross, this cancels out the per-tile transparency effect
373 // derived from weather.
374 if( outside_cache[x][y] ) {
375 prev_transparency /= sight_penalty;
376 }
377
378 if( prev_transparency > LIGHT_TRANSPARENCY_SOLID &&
379 !prev_floor_cache[prev_x][prev_y] &&
380 ( prev_light_max = prev_lm[prev_x][prev_y].max() ) > 0.0 ) {
381 const float light_level = clamp( prev_light_max * LIGHT_TRANSPARENCY_OPEN_AIR / prev_transparency,
382 inside_light_level, prev_light_max );
383
384 if( i == 0 ) {
385 lm[x][y].fill( light_level );
386 fully_inside &= light_level <= inside_light_level;
387 break;
388 } else {
389 fully_inside &= light_level <= inside_light_level;
390 lm[x][y][dir_quadrants[i][0]] = light_level;
391 lm[x][y][dir_quadrants[i][1]] = light_level;
392 }
393 }
394 }
395 }
396 }
397 }
398}
constexpr T clamp(const T &val, const T &min, const T &max)
Clamp first argument so that it is no lower than second and no higher than third.
Definition: cata_utility.h:145
int calc_max_populated_zlev()
Caclulate the greatest populated zlevel in the loaded submaps and save in the level cache.
Definition: map.cpp:8962
weather_type_id weather_id
Definition: weather.h:193
weather_manager & get_weather()
Definition: weather.cpp:64
static constexpr float LIGHT_AMBIENT_DIM
Definition: lightmap.h:16
bool floor_cache[MAPSIZE_X][MAPSIZE_Y]
Definition: map.h:328
bool outside_cache[MAPSIZE_X][MAPSIZE_Y]
Definition: map.h:322
float sight_penalty
Definition: weather_type.h:111

References calc_max_populated_zlev(), clamp(), level_cache::floor_cache, g, get_cache(), get_cache_ref(), get_weather(), inbounds(), LIGHT_AMBIENT_DIM, LIGHT_AMBIENT_LOW, LIGHT_SOURCE_BRIGHT, LIGHT_TRANSPARENCY_OPEN_AIR, LIGHT_TRANSPARENCY_SOLID, level_cache::lm, MAPSIZE_X, MAPSIZE_Y, NE, NW, level_cache::outside_cache, OVERMAP_DEPTH, OVERMAP_HEIGHT, point_east, point_north, point_south, point_west, point_zero, SE, weather_type::sight_penalty, SW, level_cache::transparency_cache, weather_manager::weather_id, point::x, point::y, and zlevels.

Referenced by generate_lightmap().

◆ build_transparency_cache()

bool map::build_transparency_cache ( int  zlev)
protected

Definition at line 82 of file lightmap.cpp.

83{
84 auto &map_cache = get_cache( zlev );
85 auto &transparency_cache = map_cache.transparency_cache;
86 auto &outside_cache = map_cache.outside_cache;
87
88 if( map_cache.transparency_cache_dirty.none() ) {
89 return false;
90 }
91
92 std::set<tripoint> vehicles_processed;
93
94 // if true, all submaps are invalid (can use batch init)
95 bool rebuild_all = map_cache.transparency_cache_dirty.all();
96
97 if( rebuild_all ) {
98 // Default to just barely not transparent.
99 std::uninitialized_fill_n( &transparency_cache[0][0], MAPSIZE_X * MAPSIZE_Y,
100 static_cast<float>( LIGHT_TRANSPARENCY_OPEN_AIR ) );
101 }
102
103 const float sight_penalty = get_weather().weather_id->sight_penalty;
104
105 // Traverse the submaps in order
106 for( int smx = 0; smx < my_MAPSIZE; ++smx ) {
107 for( int smy = 0; smy < my_MAPSIZE; ++smy ) {
108 const auto cur_submap = get_submap_at_grid( {smx, smy, zlev} );
109
110 const point sm_offset = sm_to_ms_copy( point( smx, smy ) );
111
112 if( !rebuild_all && !map_cache.transparency_cache_dirty[smx * MAPSIZE + smy] ) {
113 continue;
114 }
115
116 // calculates transparency of a single tile
117 // x,y - coords in map local coords
118 auto calc_transp = [&]( const point & p ) {
119 const point sp = p - sm_offset;
120 float value = LIGHT_TRANSPARENCY_OPEN_AIR;
121
122 if( !( cur_submap->get_ter( sp ).obj().transparent &&
123 cur_submap->get_furn( sp ).obj().transparent ) ) {
125 }
126 if( outside_cache[p.x][p.y] ) {
127 // FIXME: Places inside vehicles haven't been marked as
128 // inside yet so this is incorrectly penalising for
129 // weather in vehicles.
130 value *= sight_penalty;
131 }
132 for( const auto &fld : cur_submap->get_field( sp ) ) {
133 const field_entry &cur = fld.second;
134 if( cur.is_transparent() ) {
135 continue;
136 }
137 // Fields are either transparent or not, however we want some to be translucent
138 value = value * cur.translucency();
139 }
140 // TODO: [lightmap] Have glass reduce light as well
141 return value;
142 };
143
144 if( cur_submap->is_uniform ) {
145 float value = calc_transp( sm_offset );
146 // if rebuild_all==true all values were already set to LIGHT_TRANSPARENCY_OPEN_AIR
147 if( !rebuild_all || value != LIGHT_TRANSPARENCY_OPEN_AIR ) {
148 for( int sx = 0; sx < SEEX; ++sx ) {
149 // init all sy indices in one go
150 std::uninitialized_fill_n( &transparency_cache[sm_offset.x + sx][sm_offset.y], SEEY, value );
151 }
152 }
153 } else {
154 for( int sx = 0; sx < SEEX; ++sx ) {
155 const int x = sx + sm_offset.x;
156 for( int sy = 0; sy < SEEY; ++sy ) {
157 const int y = sy + sm_offset.y;
158 transparency_cache[x][y] = calc_transp( { x, y } );
159 }
160 }
161 }
162 }
163 }
164 map_cache.transparency_cache_dirty.reset();
165 return true;
166}
An active or passive effect existing on a tile.
Definition: field.h:20
bool is_transparent() const
Definition: field.cpp:84
float translucency() const
Definition: field.cpp:79

References get_cache(), get_submap_at_grid(), get_weather(), field_entry::is_transparent(), LIGHT_TRANSPARENCY_OPEN_AIR, LIGHT_TRANSPARENCY_SOLID, MAPSIZE, MAPSIZE_X, MAPSIZE_Y, my_MAPSIZE, SEEX, SEEY, weather_type::sight_penalty, sm_to_ms_copy(), sx, sy, field_entry::translucency(), and weather_manager::weather_id.

Referenced by build_map_cache().

◆ build_vision_transparency_cache()

bool map::build_vision_transparency_cache ( const Character player)
protected

Definition at line 168 of file lightmap.cpp.

169{
170 const tripoint &p = player.pos();
171
172 bool dirty = false;
173
175
176 const auto check_vehicle_coverage = []( const vehicle * veh, const point & p ) -> bool {
177 return veh->obstacle_at_position( p ) == -1 && ( veh->part_with_feature( p, "AISLE", true ) != -1 || veh->part_with_feature( p, "PROTRUSION", true ) != -1 );
178 };
179
180 const optional_vpart_position player_vp = veh_at( p );
181
182 point player_mount;
183 if( player_vp ) {
184 player_mount = player_vp->vehicle().tripoint_to_mount( p );
185 }
186
187 int i = 0;
188 for( const point &adjacent : eight_adjacent_offsets ) {
190
191 // If we're crouching behind an obstacle, we can't see past it.
192 if( coverage( adjacent + p ) >= 30 ) {
193 dirty = true;
195 } else {
197 adjacent ) != four_diagonal_offsets.end() ) {
198 const optional_vpart_position adjacent_vp = veh_at( p + adjacent );
199
200 point adjacent_mount;
201 if( adjacent_vp ) {
202 adjacent_mount = adjacent_vp->vehicle().tripoint_to_mount( p );
203 }
204
205 if( ( player_vp &&
206 !player_vp->vehicle().check_rotated_intervening( player_mount,
207 player_vp->vehicle().tripoint_to_mount( p + adjacent ),
208 check_vehicle_coverage ) )
209 || ( adjacent_vp && ( !player_vp || &( player_vp->vehicle() ) != &( adjacent_vp->vehicle() ) ) &&
210 !adjacent_vp->vehicle().check_rotated_intervening( adjacent_vp->vehicle().tripoint_to_mount(
211 p ), adjacent_vp->vehicle().tripoint_to_mount( p + adjacent ),
212 check_vehicle_coverage ) ) ) {
213 dirty = true;
215 }
216 }
217 }
218
219 i++;
220 }
221 } else {
222 std::fill_n( &vision_transparency_cache[0], 8, VISION_ADJUST_NONE );
223 }
224 return dirty;
225}
@ CMM_CROUCH
Definition: character.h:104
bool movement_mode_is(character_movemode mode) const
Check against the character's current movement mode.
Definition: character.cpp:1619
int coverage(const tripoint &p) const
Returns coverage value of the tile.
Definition: map.cpp:6256
int part_with_feature(int p, const std::string &f, bool unbroken) const
Definition: vehicle.cpp:2520
int obstacle_at_position(const point &pos) const
Definition: vehicle.cpp:2582
@ VISION_ADJUST_NONE
Definition: lightmap.h:77

References CMM_CROUCH, coverage(), eight_adjacent_offsets, detail::find(), four_diagonal_offsets, Character::movement_mode_is(), vehicle::obstacle_at_position(), vehicle::part_with_feature(), Character::pos(), veh_at(), VISION_ADJUST_HIDDEN, VISION_ADJUST_NONE, VISION_ADJUST_SOLID, and vision_transparency_cache.

Referenced by build_map_cache().

◆ burn_body_part()

int map::burn_body_part ( player u,
field_entry cur,
body_part  bp,
int  scale 
)
private

Definition at line 124 of file map_field.cpp.

125{
126 int total_damage = 0;
127 const int intensity = cur.get_field_intensity();
128 const int damage = rng( 1, ( scale + intensity ) / 2 );
129 // A bit ugly, but better than being annoyed by acid when in hazmat
130 if( u.get_armor_type( DT_ACID, convert_bp( bp ) ) < damage ) {
131 const dealt_damage_instance ddi = u.deal_damage( nullptr, convert_bp( bp ).id(),
132 damage_instance( DT_ACID, damage ) );
133 total_damage += ddi.total_damage();
134 }
135 // Represents acid seeping in rather than being splashed on
137 1 + intensity ) ), bp, 0 );
138 return total_damage;
139}
units::quantity< V, B > rng(const units::quantity< V, B > &min, const units::quantity< V, B > &max)
Definition: artifact.cpp:32
const bodypart_str_id & convert_bp(body_part bp)
Returns the new id for old token.
Definition: bodypart.cpp:185
dealt_damage_instance deal_damage(Creature *source, bodypart_id bp, const damage_instance &d) override
Calls Creature::deal_damage and handles damaged effects (waking up, etc.)
Definition: character.cpp:8468
int get_armor_type(damage_type dt, bodypart_id bp) const override
Returns overall resistance to given type on the bod part.
Definition: character.cpp:6987
bool add_env_effect(const efftype_id &eff_id, body_part vector, int strength, const time_duration &dur, body_part bp=num_bp, int intensity=1, bool force=false)
Gives chance to save via environmental resist, returns false if resistance was successful.
Definition: creature.cpp:1112
int get_field_intensity() const
Definition: field.cpp:121
static constexpr time_duration from_turns(const T t)
Named constructors to get a duration representing a multiple of the named time units.
Definition: calendar.h:204
@ DT_ACID
Definition: damage.h:26
static const efftype_id effect_corroding("corroding")
int total_damage() const
Definition: damage.cpp:180

References Creature::add_env_effect(), convert_bp(), Character::deal_damage(), DT_ACID, effect_corroding, time_duration::from_turns(), Character::get_armor_type(), field_entry::get_field_intensity(), rng(), and dealt_damage_instance::total_damage().

Referenced by player_in_field().

◆ calc_max_populated_zlev()

int map::calc_max_populated_zlev ( )
private

Caclulate the greatest populated zlevel in the loaded submaps and save in the level cache.

fills the map::max_populated_zlev and returns it

Returns
max_populated_zlev value

Definition at line 8962 of file map.cpp.

8963{
8964 // cache is filled and valid, skip recalculation
8966 return max_populated_zlev->second;
8967 }
8968
8969 // We'll assume ground level is populated
8970 int max_z = 0;
8971
8972 for( int sz = 1; sz <= OVERMAP_HEIGHT; sz++ ) {
8973 bool level_done = false;
8974 for( int sx = 0; sx < my_MAPSIZE; sx++ ) {
8975 for( int sy = 0; sy < my_MAPSIZE; sy++ ) {
8976 const submap *sm = get_submap_at_grid( tripoint( sx, sy, sz ) );
8977 if( !sm->is_uniform ) {
8978 max_z = sz;
8979 level_done = true;
8980 break;
8981 }
8982 }
8983 if( level_done ) {
8984 break;
8985 }
8986 }
8987 }
8988
8989 max_populated_zlev = std::pair<tripoint, int>( get_abs_sub(), max_z );
8990 return max_z;
8991}
cata::optional< std::pair< tripoint, int > > max_populated_zlev
Definition: map.h:2046
tripoint get_abs_sub() const
return abs_sub
Definition: map.cpp:8288

References get_abs_sub(), get_submap_at_grid(), max_populated_zlev, my_MAPSIZE, OVERMAP_HEIGHT, coords::sm, sx, and sy.

Referenced by build_sunlight_cache().

◆ can_move_furniture()

bool map::can_move_furniture ( const tripoint pos,
player p = nullptr 
)
Strength determines what furniture the player can move

Definition at line 1445 of file map.cpp.

1446{
1447 if( !p ) {
1448 return false;
1449 }
1450 const furn_t &furniture_type = furn( pos ).obj();
1451 int required_str = furniture_type.move_str_req;
1452
1453 // Object can not be moved (or nothing there)
1454 if( required_str < 0 ) {
1455 return false;
1456 }
1457
1458 ///\EFFECT_STR determines what furniture the player can move
1459 int adjusted_str = p->str_cur;
1460 if( p->is_mounted() ) {
1461 auto mons = p->mounted_creature.get();
1462 if( mons->has_flag( MF_RIDEABLE_MECH ) && mons->mech_str_addition() != 0 ) {
1463 adjusted_str = mons->mech_str_addition();
1464 }
1465 }
1466 return adjusted_str >= required_str;
1467}
int str_cur
Definition: character.h:247
bool is_mounted() const
Definition: character.cpp:1143
shared_ptr_fast< monster > mounted_creature
Definition: character.h:1556
@ MF_RIDEABLE_MECH
Definition: mtype.h:115
int move_str_req
Definition: mapdata.h:511

References furn(), Character::is_mounted(), MF_RIDEABLE_MECH, Character::mounted_creature, furn_t::move_str_req, int_id< T >::obj(), wrapped_vehicle::pos, and Character::str_cur.

Referenced by grab().

◆ can_put_items() [1/2]

bool map::can_put_items ( const point p) const
inline

Definition at line 969 of file map.h.

969 {
970 return can_put_items( tripoint( p, abs_sub.z ) );
971 }
bool can_put_items(const tripoint &p) const
Definition: map.cpp:2298

References abs_sub, can_put_items(), and tripoint::z.

◆ can_put_items() [2/2]

bool map::can_put_items ( const tripoint p) const

Definition at line 2298 of file map.cpp.

2299{
2300 if( can_put_items_ter_furn( p ) ) {
2301 return true;
2302 }
2303 const optional_vpart_position vp = veh_at( p );
2304 return static_cast<bool>( vp.part_with_feature( "CARGO", true ) );
2305}
bool can_put_items_ter_furn(const tripoint &p) const
Definition: map.cpp:2307

References can_put_items_ter_furn(), optional_vpart_position::part_with_feature(), and veh_at().

Referenced by can_put_items(), complete_construction(), haul(), and game::place_player().

◆ can_put_items_ter_furn() [1/2]

bool map::can_put_items_ter_furn ( const point p) const
inline

Definition at line 974 of file map.h.

974 {
976 }

References abs_sub, can_put_items_ter_furn(), and tripoint::z.

◆ can_put_items_ter_furn() [2/2]

bool map::can_put_items_ter_furn ( const tripoint p) const

◆ can_see_trap_at()

bool map::can_see_trap_at ( const tripoint p,
const Character c 
) const

See trap::can_see, which is called for the trap here.

Definition at line 5132 of file map.cpp.

5133{
5134 return tr_at( p ).can_see( p, c );
5135}
const trap & tr_at(const tripoint &p) const
Definition: map.cpp:5137
constexpr double c
Definition: magic.cpp:1032
bool can_see(const tripoint &pos, const Character &p) const
Can player/npc p see this kind of trap, either by their memory (they known there is the trap) or by t...
Definition: trap.cpp:223

References c, trap::can_see(), and tr_at().

Referenced by can_examine_at(), and vehicle::autodrive_controller::check_drivable().

◆ check_and_set_seen_cache()

bool map::check_and_set_seen_cache ( const tripoint p) const
inline

Definition at line 486 of file map.h.

486 {
487 std::bitset<MAPSIZE_X *MAPSIZE_Y> &memory_seen_cache =
489 if( !memory_seen_cache[ static_cast<size_t>( p.x + p.y * MAPSIZE_Y ) ] ) {
490 memory_seen_cache.set( static_cast<size_t>( p.x + p.y * MAPSIZE_Y ) );
491 return true;
492 }
493 return false;
494 }
std::bitset< MAPSIZE_X *MAPSIZE_Y > map_memory_seen_cache
Definition: map.h:351

References get_cache(), level_cache::map_memory_seen_cache, MAPSIZE_Y, tripoint::x, tripoint::y, and tripoint::z.

Referenced by draw_maptile().

◆ check_seen_cache()

bool map::check_seen_cache ( const tripoint p) const
inline

Definition at line 481 of file map.h.

481 {
482 std::bitset<MAPSIZE_X *MAPSIZE_Y> &memory_seen_cache =
484 return !memory_seen_cache[ static_cast<size_t>( p.x + p.y * MAPSIZE_Y ) ];
485 }

References get_cache(), level_cache::map_memory_seen_cache, MAPSIZE_Y, tripoint::x, tripoint::y, and tripoint::z.

◆ check_submap_active_item_consistency()

std::vector< tripoint > map::check_submap_active_item_consistency ( )

Definition at line 4554 of file map.cpp.

4555{
4556 std::vector<tripoint> result;
4557 for( int z = -OVERMAP_DEPTH; z < OVERMAP_HEIGHT; ++z ) {
4558 for( int x = 0; x < MAPSIZE; ++x ) {
4559 for( int y = 0; y < MAPSIZE; ++y ) {
4560 tripoint p( x, y, z );
4561 submap *s = get_submap_at_grid( p );
4562 bool has_active_items = !s->active_items.get().empty();
4563 bool map_has_active_items = submaps_with_active_items.count( p + abs_sub.xy() );
4564 if( has_active_items != map_has_active_items ) {
4565 result.push_back( p + abs_sub.xy() );
4566 }
4567 }
4568 }
4569 }
4570 for( const tripoint &p : submaps_with_active_items ) {
4571 tripoint rel = p - abs_sub.xy();
4573 if( !map.contains( rel.xy() ) ) {
4574 result.push_back( p );
4575 }
4576 }
4577 return result;
4578}
std::vector< item_reference > get()
Returns a vector of all cached active item references.
Manage and cache data about a part of the map.
Definition: map.h:384

References abs_sub, submap::active_items, active_item_cache::get(), get_submap_at_grid(), map(), MAPSIZE, OVERMAP_DEPTH, OVERMAP_HEIGHT, point_zero, submaps_with_active_items, and tripoint::xy().

◆ check_vehicle_zones()

bool map::check_vehicle_zones ( int  zlev)

Definition at line 929 of file map.cpp.

930{
931 for( auto veh : get_cache( zlev ).zone_vehicles ) {
932 if( veh->zones_dirty ) {
933 return true;
934 }
935 }
936 return false;
937}

References get_cache().

Referenced by activity_on_turn_move_loot(), talk_function::basecamp_mission(), basecamp::distribute_food(), find_auto_consume(), basecamp::place_results(), and basecamp::validate_sort_points().

◆ clear_path()

bool map::clear_path ( const tripoint f,
const tripoint t,
int  range,
int  cost_min,
int  cost_max 
) const

Check whether there's a direct line of sight between F and T with the additional movecost restraints.

Checks two things:

  1. The sees() algorithm between F and T
  2. That moving over the line of sight would have a move_cost between cost_min and cost_max.

Definition at line 6407 of file map.cpp.

6409{
6410 // Ugly `if` for now
6411 if( !fov_3d && f.z != t.z ) {
6412 return false;
6413 }
6414
6415 if( f.z == t.z ) {
6416 if( ( range >= 0 && range < rl_dist( f.xy(), t.xy() ) ) ||
6417 !inbounds( t ) ) {
6418 return false; // Out of range!
6419 }
6420 bool is_clear = true;
6421 point last_point = f.xy();
6422 bresenham( f.xy(), t.xy(), 0,
6423 [this, &is_clear, cost_min, cost_max, &t, &last_point]( const point & new_point ) {
6424 // Exit before checking the last square, it's still reachable even if it is an obstacle.
6425 if( new_point.x == t.x && new_point.y == t.y ) {
6426 return false;
6427 }
6428
6429 const int cost = this->move_cost( new_point );
6430 if( cost < cost_min || cost > cost_max ||
6431 obstructed_by_vehicle_rotation( tripoint( last_point, t.z ), tripoint( new_point,
6432 t.z ) ) ) {
6433 is_clear = false;
6434 return false;
6435 }
6436
6437 last_point = new_point;
6438 return true;
6439 } );
6440 return is_clear;
6441 }
6442
6443 if( ( range >= 0 && range < rl_dist( f, t ) ) ||
6444 !inbounds( t ) ) {
6445 return false; // Out of range!
6446 }
6447 bool is_clear = true;
6448 tripoint last_point = f;
6449 bresenham( f, t, 0, 0,
6450 [this, &is_clear, cost_min, cost_max, t, &last_point]( const tripoint & new_point ) {
6451 // Exit before checking the last square, it's still reachable even if it is an obstacle.
6452 if( new_point == t ) {
6453 return false;
6454 }
6455
6456 // We have to check a weird case where the move is both vertical and horizontal
6457 if( new_point.z == last_point.z ) {
6458 const int cost = move_cost( new_point );
6459 if( cost < cost_min || cost > cost_max ||
6460 obstructed_by_vehicle_rotation( last_point, new_point ) ) {
6461 is_clear = false;
6462 return false;
6463 }
6464 } else {
6465 bool this_clear = false;
6466 const int max_z = std::max( new_point.z, last_point.z );
6467 if( !has_floor_or_support( {new_point.xy(), max_z} ) ) {
6468 const int cost = move_cost( {new_point.xy(), last_point.z} );
6469 if( cost > cost_min && cost < cost_max &&
6470 !obstructed_by_vehicle_rotation( last_point, new_point ) ) {
6471 this_clear = true;
6472 }
6473 }
6474
6475 if( !this_clear && has_floor_or_support( {last_point.xy(), max_z} ) ) {
6476 const int cost = move_cost( {last_point.xy(), new_point.z} );
6477 if( cost > cost_min && cost < cost_max &&
6478 !obstructed_by_vehicle_rotation( last_point, new_point ) ) {
6479 this_clear = true;
6480 }
6481 }
6482
6483 if( !this_clear ) {
6484 is_clear = false;
6485 return false;
6486 }
6487 }
6488
6489 last_point = new_point;
6490 return true;
6491 } );
6492 return is_clear;
6493}
bool has_floor_or_support(const tripoint &p) const
Definition: map.cpp:2039
int move_cost(const tripoint &p, const vehicle *ignored_vehicle=nullptr) const
Calculate the cost to move past the tile at p.
Definition: map.cpp:1780
void bresenham(const point &p1, const point &p2, int t, const std::function< bool(const point &)> &interact)
The actual Bresenham algorithm in 2D and 3D, everything else should call these and pass in an interac...
Definition: line.cpp:24

References bresenham(), fov_3d, inbounds(), obstructed_by_vehicle_rotation(), rl_dist(), tripoint::xy(), and tripoint::z.

Referenced by find_best_fire(), player::get_eligible_containers_for_crafting(), has_clear_path_to_pickup_items(), points_for_gas_cloud(), process_fields_in_submap(), mattack::riotbot(), game::start_game(), and vehicle_selector::vehicle_selector().

◆ clear_spawns()

void map::clear_spawns ( )

Definition at line 7735 of file map.cpp.

7736{
7737 for( auto &smap : grid ) {
7738 smap->spawns.clear();
7739 }
7740}

References grid.

Referenced by defense_game::init_map().

◆ clear_traps()

void map::clear_traps ( )

Definition at line 7742 of file map.cpp.

7743{
7744 for( auto &smap : grid ) {
7745 for( int x = 0; x < SEEX; x++ ) {
7746 for( int y = 0; y < SEEY; y++ ) {
7747 const point p( x, y );
7748 smap->set_trap( p, tr_null );
7749 }
7750 }
7751 }
7752
7753 // Forget about all trap locations.
7754 for( auto &i : traplocs ) {
7755 i.clear();
7756 }
7757}

References grid, SEEX, SEEY, tr_null, and traplocs.

Referenced by defense_game::init_map().

◆ clear_vehicle_cache()

void map::clear_vehicle_cache ( )

Definition at line 313 of file map.cpp.

314{
315 const int zmin = zlevels ? -OVERMAP_DEPTH : abs_sub.z;
316 const int zmax = zlevels ? OVERMAP_HEIGHT : abs_sub.z;
317 for( int zlev = zmin; zlev <= zmax; zlev++ ) {
318 level_cache &ch = get_cache( zlev );
319 while( !ch.veh_cached_parts.empty() ) {
320 const auto part = ch.veh_cached_parts.begin();
321 const auto &p = part->first;
322 if( inbounds( p ) ) {
323 ch.veh_exists_at[p.x][p.y] = false;
324 }
325 ch.veh_cached_parts.erase( part );
326 }
327 ch.veh_in_active_range = false;
328 }
329}

References abs_sub, get_cache(), inbounds(), OVERMAP_DEPTH, OVERMAP_HEIGHT, level_cache::veh_cached_parts, level_cache::veh_exists_at, level_cache::veh_in_active_range, tripoint::z, and zlevels.

Referenced by editmap::mapgen_preview(), game::place_player_overmap(), reset_vehicle_cache(), rotate(), shift(), and game::vertical_shift().

◆ clear_vehicle_list()

void map::clear_vehicle_list ( int  zlev)

Definition at line 331 of file map.cpp.

332{
333 auto &ch = get_cache( zlev );
334 ch.vehicle_list.clear();
335 ch.zone_vehicles.clear();
336
338}

References get_cache(), and last_full_vehicle_list_dirty.

Referenced by editmap::mapgen_preview(), editmap::mapgen_veh_destroy(), game::place_player_overmap(), rotate(), and shift().

◆ clear_vehicle_point_from_cache()

void map::clear_vehicle_point_from_cache ( vehicle veh,
const tripoint pt 
)

Definition at line 295 of file map.cpp.

296{
297 if( veh == nullptr ) {
298 debugmsg( "Tried to clear null vehicle from cache" );
299 return;
300 }
301
302 level_cache &ch = get_cache( pt.z );
303 if( inbounds( pt ) ) {
304 ch.veh_exists_at[pt.x][pt.y] = false;
305 }
306 auto it = ch.veh_cached_parts.find( pt );
307 if( it != ch.veh_cached_parts.end() && it->second.first == veh ) {
308 ch.veh_cached_parts.erase( it );
309 }
310
311}

References debugmsg, get_cache(), inbounds(), level_cache::veh_cached_parts, level_cache::veh_exists_at, tripoint::x, tripoint::y, and tripoint::z.

Referenced by vehicle::advance_precalc_mounts(), veh_interact::complete_vehicle(), and vehicle::part_removal_cleanup().

◆ climb_difficulty()

int map::climb_difficulty ( const tripoint p) const

Checks 3x3 block centered on p for terrain to climb.

Returns
Difficulty of climbing check from point p.

Definition at line 1969 of file map.cpp.

1970{
1971 if( p.z > OVERMAP_HEIGHT || p.z < -OVERMAP_DEPTH ) {
1972 debugmsg( "climb_difficulty on out of bounds point: %d, %d, %d", p.x, p.y, p.z );
1973 return INT_MAX;
1974 }
1975
1976 int best_difficulty = INT_MAX;
1977 int blocks_movement = 0;
1978 if( has_flag( "LADDER", p ) ) {
1979 // Really easy, but you have to stand on the tile
1980 return 1;
1981 } else if( has_flag( TFLAG_RAMP, p ) || has_flag( TFLAG_RAMP_UP, p ) ||
1982 has_flag( TFLAG_RAMP_DOWN, p ) ) {
1983 // We're on something stair-like, so halfway there already
1984 best_difficulty = 7;
1985 }
1986
1987 for( const auto &pt : points_in_radius( p, 1 ) ) {
1988 if( impassable_ter_furn( pt ) ) {
1989 // TODO: Non-hardcoded climbability
1990 best_difficulty = std::min( best_difficulty, 10 );
1991 blocks_movement++;
1992 } else if( veh_at( pt ) ) {
1993 // Vehicle tiles are quite good for climbing
1994 // TODO: Penalize spiked parts?
1995 best_difficulty = std::min( best_difficulty, 7 );
1996 }
1997
1998 if( best_difficulty > 5 && has_flag( "CLIMBABLE", pt ) ) {
1999 best_difficulty = 5;
2000 }
2001 }
2002
2003 // TODO: Make this more sensible - check opposite sides, not just movement blocker count
2004 return best_difficulty - blocks_movement;
2005}
bool impassable_ter_furn(const tripoint &p) const
Definition: map.cpp:1828
@ TFLAG_RAMP_UP
Definition: mapdata.h:313
@ TFLAG_RAMP
Definition: mapdata.h:314
@ TFLAG_RAMP_DOWN
Definition: mapdata.h:312

References debugmsg, has_flag(), impassable_ter_furn(), OVERMAP_DEPTH, OVERMAP_HEIGHT, points_in_radius(), TFLAG_RAMP, TFLAG_RAMP_DOWN, TFLAG_RAMP_UP, veh_at(), tripoint::x, tripoint::y, and tripoint::z.

Referenced by map_funcs::climbing_cost().

◆ clip_to_bounds() [1/3]

void map::clip_to_bounds ( int &  x,
int &  y 
) const

Definition at line 8905 of file map.cpp.

8906{
8907 if( x < 0 ) {
8908 x = 0;
8909 } else if( x >= SEEX * my_MAPSIZE ) {
8910 x = SEEX * my_MAPSIZE - 1;
8911 }
8912
8913 if( y < 0 ) {
8914 y = 0;
8915 } else if( y >= SEEY * my_MAPSIZE ) {
8916 y = SEEY * my_MAPSIZE - 1;
8917 }
8918}

References my_MAPSIZE, SEEX, and SEEY.

◆ clip_to_bounds() [2/3]

void map::clip_to_bounds ( int &  x,
int &  y,
int &  z 
) const

Definition at line 8920 of file map.cpp.

8921{
8922 clip_to_bounds( x, y );
8923 if( z < -OVERMAP_DEPTH ) {
8924 z = -OVERMAP_DEPTH;
8925 } else if( z > OVERMAP_HEIGHT ) {
8926 z = OVERMAP_HEIGHT;
8927 }
8928}
void clip_to_bounds(tripoint &p) const
Clips the coordinates of p to fit the map bounds.
Definition: map.cpp:8900

References clip_to_bounds(), OVERMAP_DEPTH, and OVERMAP_HEIGHT.

◆ clip_to_bounds() [3/3]

void map::clip_to_bounds ( tripoint p) const

Clips the coordinates of p to fit the map bounds.

Definition at line 8900 of file map.cpp.

8901{
8902 clip_to_bounds( p.x, p.y, p.z );
8903}

References clip_to_bounds(), tripoint::x, tripoint::y, and tripoint::z.

Referenced by MapgenRemovePartHandler::add_item_or_charges(), clip_to_bounds(), and route().

◆ close_door()

bool map::close_door ( const tripoint p,
bool  inside,
bool  check_only 
)

Definition at line 3974 of file map.cpp.

3975{
3976 if( has_flag( "OPENCLOSE_INSIDE", p ) && !inside ) {
3977 return false;
3978 }
3979
3980 const auto &ter = this->ter( p ).obj();
3981 const auto &furn = this->furn( p ).obj();
3982 if( ter.close && !furn.id ) {
3983 if( !check_only ) {
3984 sounds::sound( p, 10, sounds::sound_t::movement, _( "swish" ), true,
3985 "close_door", ter.id.str() );
3986 ter_set( p, ter.close );
3987 }
3988 return true;
3989 } else if( furn.close ) {
3990 if( !check_only ) {
3991 sounds::sound( p, 10, sounds::sound_t::movement, _( "swish" ), true,
3992 "close_door", furn.id.str() );
3993 furn_set( p, furn.close );
3994 }
3995 return true;
3996 }
3997 return false;
3998}
const string_id< T > & id() const
Definition: ammo_effect.cpp:33

References _, furn(), furn_set(), has_flag(), int_id< T >::id(), sounds::movement, int_id< T >::obj(), sounds::sound(), string_id< T >::str(), ter(), and ter_set().

Referenced by can_interact_at(), doors::close_door(), and game::try_get_right_click_action().

◆ collapse_at()

void map::collapse_at ( const tripoint p,
bool  silent,
bool  was_supporting = false,
bool  destroy_pos = true 
)

Causes a collapse at p, such as from destroying a wall.

Definition at line 2909 of file map.cpp.

2911{
2912 const bool supports = was_supporting || has_flag( TFLAG_SUPPORTS_ROOF, p );
2913 const bool wall = was_supporting || has_flag( TFLAG_WALL, p );
2914 // don't bash again if the caller already bashed here
2915 if( destroy_pos ) {
2916 destroy( p, silent );
2917 crush( p );
2918 make_rubble( p );
2919 }
2920 const bool still_supports = has_flag( TFLAG_SUPPORTS_ROOF, p );
2921
2922 // If something supporting the roof collapsed, see what else collapses
2923 if( supports && !still_supports ) {
2924 for( const tripoint &t : points_in_radius( p, 1 ) ) {
2925 // If z-levels are off, tz == t, so we end up skipping a lot of stuff to avoid bugs.
2926 const tripoint &tz = tripoint( t.xy(), t.z + 1 );
2927 // if nothing above us had the chance of collapsing, move on
2928 if( !one_in( collapse_check( tz ) ) ) {
2929 continue;
2930 }
2931 // if a wall collapses, walls without support from below risk collapsing and
2932 //propagate the collapse upwards
2933 if( zlevels && wall && p == t && has_flag( TFLAG_WALL, tz ) ) {
2934 collapse_at( tz, silent );
2935 }
2936 // floors without support from below risk collapsing into open air and can propagate
2937 // the collapse horizontally but not vertically
2938 if( p != t && ( has_flag( TFLAG_SUPPORTS_ROOF, t ) && has_flag( TFLAG_COLLAPSES, t ) ) ) {
2939 collapse_at( t, silent );
2940 }
2941 // this tile used to support a roof, now it doesn't, which means there is only
2942 // open air above us
2943 if( zlevels ) {
2944 ter_set( tz, t_open_air );
2945 furn_set( tz, f_null );
2947 }
2948 }
2949 }
2950 // it would be great to check if collapsing ceilings smashed through the floor, but
2951 // that's not handled for now
2952}
void crush(const tripoint &p)
Definition: map.cpp:3672
int collapse_check(const tripoint &p)
Checks if a square should collapse, returns the X for the one_in(X) collapse chance.
Definition: map.cpp:2860
void make_rubble(const tripoint &p, const furn_id &rubble_type, bool items, const ter_id &floor_type, bool overwrite=false)
Generates rubble at the given location, if overwrite is true it just writes on top of what currently ...
Definition: map.cpp:2509
@ TFLAG_COLLAPSES
Definition: mapdata.h:288
@ TFLAG_WALL
Definition: mapdata.h:300

References collapse_at(), collapse_check(), crush(), destroy(), f_null, furn_set(), has_flag(), make_rubble(), one_in(), points_in_radius(), propagate_suspension_check(), silent, t_open_air, ter_set(), TFLAG_COLLAPSES, TFLAG_SUPPORTS_ROOF, TFLAG_WALL, and zlevels.

Referenced by bash_ter_success(), collapse_at(), and talk_function::loot_building().

◆ collapse_check()

int map::collapse_check ( const tripoint p)

Checks if a square should collapse, returns the X for the one_in(X) collapse chance.

Definition at line 2860 of file map.cpp.

2861{
2862 const bool collapses = has_flag( TFLAG_COLLAPSES, p );
2863 const bool supports_roof = has_flag( TFLAG_SUPPORTS_ROOF, p );
2864
2865 int num_supports = p.z == -OVERMAP_DEPTH ? 0 : -5;
2866 // if there's support below, things are less likely to collapse
2867 if( p.z > -OVERMAP_DEPTH ) {
2868 const tripoint &pbelow = tripoint( p.xy(), p.z - 1 );
2869 for( const tripoint &tbelow : points_in_radius( pbelow, 1 ) ) {
2870 if( has_flag( TFLAG_SUPPORTS_ROOF, pbelow ) ) {
2871 num_supports += 1;
2872 if( has_flag( TFLAG_WALL, pbelow ) ) {
2873 num_supports += 2;
2874 }
2875 if( tbelow == pbelow ) {
2876 num_supports += 2;
2877 }
2878 }
2879 }
2880 }
2881
2882 for( const tripoint &t : points_in_radius( p, 1 ) ) {
2883 if( p == t ) {
2884 continue;
2885 }
2886
2887 if( collapses ) {
2888 if( has_flag( TFLAG_COLLAPSES, t ) ) {
2889 num_supports++;
2890 } else if( has_flag( TFLAG_SUPPORTS_ROOF, t ) ) {
2891 num_supports += 2;
2892 }
2893 } else if( supports_roof ) {
2894 if( has_flag( TFLAG_SUPPORTS_ROOF, t ) ) {
2895 if( has_flag( TFLAG_WALL, t ) ) {
2896 num_supports += 4;
2897 } else if( !has_flag( TFLAG_COLLAPSES, t ) ) {
2898 num_supports += 3;
2899 }
2900 }
2901 }
2902 }
2903
2904 return 1.7 * num_supports;
2905}

References has_flag(), OVERMAP_DEPTH, points_in_radius(), TFLAG_COLLAPSES, TFLAG_SUPPORTS_ROOF, TFLAG_WALL, tripoint::xy(), and tripoint::z.

Referenced by collapse_at().

◆ collapse_invalid_suspension()

void map::collapse_invalid_suspension ( const tripoint point)

Triggers a recursive collapse of suspended tiles based on their support validity.

Definition at line 2963 of file map.cpp.

2964{
2965 if( !is_suspension_valid( point ) ) {
2967 furn_set( point, f_null );
2968
2970 }
2971}
bool is_suspension_valid(const tripoint &point)
Checks the four orientations in which a suspended tile could be valid, and returns if the tile is val...
Definition: map.cpp:2973

References f_null, furn_set(), is_suspension_valid(), propagate_suspension_check(), t_open_air, and ter_set().

Referenced by drop_everything(), and propagate_suspension_check().

◆ combined_movecost()

int map::combined_movecost ( const tripoint from,
const tripoint to,
const vehicle ignored_vehicle = nullptr,
int  modifier = 0,
bool  flying = false,
bool  via_ramp = false 
) const

Cost to move out of one tile and into the next.

Returns
The cost in turns to move out of tripoint from and into to

Definition at line 1838 of file map.cpp.

1841{
1842 const int mults[4] = { 0, 50, 71, 100 };
1843 const int cost1 = move_cost( from, ignored_vehicle );
1844 const int cost2 = move_cost( to, ignored_vehicle );
1845 // Multiply cost depending on the number of differing axes
1846 // 0 if all axes are equal, 100% if only 1 differs, 141% for 2, 200% for 3
1847 size_t match = trigdist ? ( from.x != to.x ) + ( from.y != to.y ) + ( from.z != to.z ) : 1;
1848 if( flying || from.z == to.z ) {
1849 return ( cost1 + cost2 + modifier ) * mults[match] / 2;
1850 }
1851
1852 // Inter-z-level movement by foot (not flying)
1853 if( !valid_move( from, to, false, via_ramp ) ) {
1854 return 0;
1855 }
1856
1857 // TODO: Penalize for using stairs
1858 return ( cost1 + cost2 + modifier ) * mults[match] / 2;
1859}
bool valid_move(const tripoint &from, const tripoint &to, bool bash=false, bool flying=false, bool via_ramp=false) const
Returns true if a creature could walk from from to to in one step.
Definition: map.cpp:1861

References move_cost(), trigdist, valid_move(), tripoint::x, tripoint::y, and tripoint::z.

Referenced by npc::move_away_from(), npc::move_to(), and game::walk_move().

◆ computer_at()

computer * map::computer_at ( const tripoint p)

Definition at line 5554 of file map.cpp.

5555{
5556 if( !inbounds( p ) ) {
5557 return nullptr;
5558 }
5559
5560 point l;
5561 submap *const sm = get_submap_at( p, l );
5562 return sm->get_computer( l );
5563}

References get_submap_at(), inbounds(), and coords::sm.

Referenced by mission_start::reveal_lab_train_depot(), and game::use_computer().

◆ copy_grid()

void map::copy_grid ( const tripoint to,
const tripoint from 
)
protected

Definition at line 7520 of file map.cpp.

7521{
7522 const auto smap = get_submap_at_grid( from );
7523 setsubmap( get_nonant( to ), smap );
7524 for( auto &it : smap->vehicles ) {
7525 it->sm_pos = to;
7526 }
7527}
void setsubmap(size_t grididx, submap *smap)
Set the submap pointer in grid at the give index.
Definition: map.cpp:8302
size_t get_nonant(const tripoint &gridp) const
Get the index of a submap pointer in the grid given by grid coordinates.
Definition: map.cpp:8335

References get_nonant(), get_submap_at_grid(), and setsubmap().

Referenced by shift().

◆ could_see_items() [1/2]

bool map::could_see_items ( const tripoint p,
const Creature who 
) const

Check if the creature could see items at p if there were any items.

This is similar to sees_some_items, but it does not check that there are actually any items.

Definition at line 4747 of file map.cpp.

4748{
4749 return could_see_items( p, who.pos() );
4750}
virtual const tripoint & pos() const =0
bool could_see_items(const tripoint &p, const Creature &who) const
Check if the creature could see items at p if there were any items.
Definition: map.cpp:4747

References could_see_items(), and Creature::pos().

Referenced by could_see_items(), game::print_items_info(), and sees_some_items().

◆ could_see_items() [2/2]

bool map::could_see_items ( const tripoint p,
const tripoint from 
) const

Definition at line 4752 of file map.cpp.

4753{
4754 static const std::string container_string( "CONTAINER" );
4755 const bool container = has_flag_ter_or_furn( container_string, p );
4756 const bool sealed = has_flag_ter_or_furn( TFLAG_SEALED, p );
4757 if( sealed && container ) {
4758 // never see inside of sealed containers
4759 return false;
4760 }
4761 if( container ) {
4762 // can see inside of containers if adjacent or
4763 // on top of the container
4764 return ( std::abs( p.x - from.x ) <= 1 &&
4765 std::abs( p.y - from.y ) <= 1 &&
4766 std::abs( p.z - from.z ) <= 1 );
4767 }
4768 return true;
4769}
bool has_flag_ter_or_furn(const std::string &flag, const tripoint &p) const
Definition: map.cpp:2322
@ TFLAG_SEALED
Definition: mapdata.h:285

References has_flag_ter_or_furn(), TFLAG_SEALED, tripoint::x, tripoint::y, and tripoint::z.

◆ coverage()

int map::coverage ( const tripoint p) const

Returns coverage value of the tile.

Definition at line 6256 of file map.cpp.

6257{
6258 if( const auto obstacle_f = furn( p ) ) {
6259 return obstacle_f->coverage;
6260 }
6261 if( const auto vp = veh_at( p ) ) {
6262 if( vp->obstacle_at_part() ) {
6263 return 60;
6264 } else if( !vp->part_with_feature( VPFLAG_AISLE, true ) &&
6265 !vp->part_with_feature( "PROTRUSION", true ) ) {
6266 return 45;
6267 }
6268 }
6269 return ter( p )->coverage;
6270}
@ VPFLAG_AISLE
Definition: veh_type.h:40

References map_data_common_t::coverage, furn(), ter(), veh_at(), and VPFLAG_AISLE.

Referenced by build_vision_transparency_cache(), and game::print_terrain_info().

◆ create_anomaly() [1/2]

void map::create_anomaly ( const point cp,
artifact_natural_property  prop,
bool  create_rubble = true 
)
inline

Definition at line 1391 of file map.h.

1391 {
1392 create_anomaly( tripoint( cp, abs_sub.z ), prop, create_rubble );
1393 }
void create_anomaly(const tripoint &p, artifact_natural_property prop, bool create_rubble=true)
Definition: mapgen.cpp:6327

References abs_sub, create_anomaly(), and tripoint::z.

◆ create_anomaly() [2/2]

void map::create_anomaly ( const tripoint p,
artifact_natural_property  prop,
bool  create_rubble = true 
)

Definition at line 6327 of file mapgen.cpp.

6328{
6329 // TODO: Z
6330 point c( cp.xy() );
6331 if( create_rubble ) {
6332 rough_circle( this, t_dirt, c, 11 );
6333 rough_circle_furn( this, f_rubble, c, 5 );
6334 furn_set( c, f_null );
6335 }
6336 switch( prop ) {
6337 case ARTPROP_WRIGGLING:
6338 case ARTPROP_MOVING:
6339 for( int i = c.x - 5; i <= c.x + 5; i++ ) {
6340 for( int j = c.y - 5; j <= c.y + 5; j++ ) {
6341 if( furn( point( i, j ) ) == f_rubble ) {
6342 add_field( {i, j, abs_sub.z}, fd_push_items, 1 );
6343 if( one_in( 3 ) ) {
6344 spawn_item( point( i, j ), "rock" );
6345 }
6346 }
6347 }
6348 }
6349 break;
6350
6351 case ARTPROP_GLOWING:
6352 case ARTPROP_GLITTERING:
6353 for( int i = c.x - 5; i <= c.x + 5; i++ ) {
6354 for( int j = c.y - 5; j <= c.y + 5; j++ ) {
6355 if( furn( point( i, j ) ) == f_rubble && one_in( 2 ) ) {
6356 mtrap_set( this, point( i, j ), tr_glow );
6357 }
6358 }
6359 }
6360 break;
6361
6362 case ARTPROP_HUMMING:
6363 case ARTPROP_RATTLING:
6364 for( int i = c.x - 5; i <= c.x + 5; i++ ) {
6365 for( int j = c.y - 5; j <= c.y + 5; j++ ) {
6366 if( furn( point( i, j ) ) == f_rubble && one_in( 2 ) ) {
6367 mtrap_set( this, point( i, j ), tr_hum );
6368 }
6369 }
6370 }
6371 break;
6372
6373 case ARTPROP_WHISPERING:
6374 case ARTPROP_ENGRAVED:
6375 for( int i = c.x - 5; i <= c.x + 5; i++ ) {
6376 for( int j = c.y - 5; j <= c.y + 5; j++ ) {
6377 if( furn( point( i, j ) ) == f_rubble && one_in( 3 ) ) {
6378 mtrap_set( this, point( i, j ), tr_shadow );
6379 }
6380 }
6381 }
6382 break;
6383
6384 case ARTPROP_BREATHING:
6385 for( int i = c.x - 1; i <= c.x + 1; i++ ) {
6386 for( int j = c.y - 1; j <= c.y + 1; j++ ) {
6387 if( i == c.x && j == c.y ) {
6388 place_spawns( GROUP_BREATHER_HUB, 1, point( i, j ), point( i, j ), 1,
6389 true );
6390 } else {
6391 place_spawns( GROUP_BREATHER, 1, point( i, j ), point( i, j ), 1, true );
6392 }
6393 }
6394 }
6395 break;
6396
6397 case ARTPROP_DEAD:
6398 for( int i = c.x - 5; i <= c.x + 5; i++ ) {
6399 for( int j = c.y - 5; j <= c.y + 5; j++ ) {
6400 if( furn( point( i, j ) ) == f_rubble ) {
6401 mtrap_set( this, point( i, j ), tr_drain );
6402 }
6403 }
6404 }
6405 break;
6406
6407 case ARTPROP_ITCHY:
6408 for( int i = c.x - 5; i <= c.x + 5; i++ ) {
6409 for( int j = c.y - 5; j <= c.y + 5; j++ ) {
6410 if( furn( point( i, j ) ) == f_rubble ) {
6411 set_radiation( point( i, j ), rng( 0, 10 ) );
6412 }
6413 }
6414 }
6415 break;
6416
6417 case ARTPROP_ELECTRIC:
6418 case ARTPROP_CRACKLING:
6419 add_field( {c, abs_sub.z}, fd_shock_vent, 3 );
6420 break;
6421
6422 case ARTPROP_SLIMY:
6423 add_field( {c, abs_sub.z}, fd_acid_vent, 3 );
6424 break;
6425
6426 case ARTPROP_WARM:
6427 for( int i = c.x - 5; i <= c.x + 5; i++ ) {
6428 for( int j = c.y - 5; j <= c.y + 5; j++ ) {
6429 if( furn( point( i, j ) ) == f_rubble ) {
6430 add_field( {i, j, abs_sub.z}, fd_fire_vent, 1 + ( rl_dist( c, point( i, j ) ) % 3 ) );
6431 }
6432 }
6433 }
6434 break;
6435
6436 case ARTPROP_SCALED:
6437 for( int i = c.x - 5; i <= c.x + 5; i++ ) {
6438 for( int j = c.y - 5; j <= c.y + 5; j++ ) {
6439 if( furn( point( i, j ) ) == f_rubble ) {
6440 mtrap_set( this, point( i, j ), tr_snake );
6441 }
6442 }
6443 }
6444 break;
6445
6446 case ARTPROP_FRACTAL:
6447 create_anomaly( c + point( -4, -4 ),
6448 static_cast<artifact_natural_property>( rng( ARTPROP_NULL + 1, ARTPROP_MAX - 1 ) ) );
6449 create_anomaly( c + point( 4, -4 ),
6450 static_cast<artifact_natural_property>( rng( ARTPROP_NULL + 1, ARTPROP_MAX - 1 ) ) );
6451 create_anomaly( c + point( -4, 4 ),
6452 static_cast<artifact_natural_property>( rng( ARTPROP_NULL + 1, ARTPROP_MAX - 1 ) ) );
6453 create_anomaly( c + point( 4, -4 ),
6454 static_cast<artifact_natural_property>( rng( ARTPROP_NULL + 1, ARTPROP_MAX - 1 ) ) );
6455 break;
6456 default:
6457 break;
6458 }
6459}
bool add_field(const tripoint &p, const field_type_id &type_id, int intensity=INT_MAX, const time_duration &age=0_turns, bool hit_player=true)
Add field entry at point, or set intensity if present.
Definition: map.cpp:5408
void place_spawns(const mongroup_id &group, int chance, const point &p1, const point &p2, float density, bool individual=false, bool friendly=false, const std::string &name="NONE", int mission_id=-1)
Definition: mapgen.cpp:5396
void set_radiation(const tripoint &p, int value)
Definition: map.cpp:4046
void spawn_item(const tripoint &p, const itype_id &type_id, unsigned quantity=1, int charges=0, const time_point &birthday=calendar::start_of_cataclysm, int damlevel=0)
Definition: map.cpp:4194
artifact_natural_property
Definition: enums.h:152
@ ARTPROP_GLITTERING
Definition: enums.h:162
@ ARTPROP_ITCHY
Definition: enums.h:161
@ ARTPROP_RATTLING
Definition: enums.h:168
@ ARTPROP_WRIGGLING
Definition: enums.h:154
@ ARTPROP_HUMMING
Definition: enums.h:156
@ ARTPROP_WHISPERING
Definition: enums.h:158
@ ARTPROP_ENGRAVED
Definition: enums.h:165
@ ARTPROP_ELECTRIC
Definition: enums.h:163
@ ARTPROP_FRACTAL
Definition: enums.h:170
@ ARTPROP_SCALED
Definition: enums.h:169
@ ARTPROP_GLOWING
Definition: enums.h:155
@ ARTPROP_NULL
Definition: enums.h:153
@ ARTPROP_DEAD
Definition: enums.h:160
@ ARTPROP_BREATHING
Definition: enums.h:159
@ ARTPROP_MAX
Definition: enums.h:171
@ ARTPROP_CRACKLING
Definition: enums.h:166
@ ARTPROP_WARM
Definition: enums.h:167
@ ARTPROP_MOVING
Definition: enums.h:157
@ ARTPROP_SLIMY
Definition: enums.h:164
field_type_id fd_fire_vent
Definition: field_type.cpp:351
field_type_id fd_acid_vent
Definition: field_type.cpp:357
field_type_id fd_push_items
Definition: field_type.cpp:355
field_type_id fd_shock_vent
Definition: field_type.cpp:356
furn_id f_rubble
Definition: mapdata.cpp:1097
void rough_circle(map *m, const ter_id &type, const point &p, int rad)
Definition: mapgen.cpp:6494
void rough_circle_furn(map *m, const furn_id &type, const point &p, int rad)
Definition: mapgen.cpp:6498
static const mongroup_id GROUP_BREATHER("GROUP_BREATHER")
static const mongroup_id GROUP_BREATHER_HUB("GROUP_BREATHER_HUB")
void mtrap_set(map *m, const point &p, trap_id type)
static const trap_str_id tr_drain("tr_drain")
static const trap_str_id tr_snake("tr_snake")
static const trap_str_id tr_shadow("tr_shadow")
trap_id tr_glow
Definition: trap.cpp:312
trap_id tr_hum
Definition: trap.cpp:313

References abs_sub, add_field(), ARTPROP_BREATHING, ARTPROP_CRACKLING, ARTPROP_DEAD, ARTPROP_ELECTRIC, ARTPROP_ENGRAVED, ARTPROP_FRACTAL, ARTPROP_GLITTERING, ARTPROP_GLOWING, ARTPROP_HUMMING, ARTPROP_ITCHY, ARTPROP_MAX, ARTPROP_MOVING, ARTPROP_NULL, ARTPROP_RATTLING, ARTPROP_SCALED, ARTPROP_SLIMY, ARTPROP_WARM, ARTPROP_WHISPERING, ARTPROP_WRIGGLING, c, create_anomaly(), f_null, f_rubble, fd_acid_vent, fd_fire_vent, fd_push_items, fd_shock_vent, furn(), furn_set(), GROUP_BREATHER, GROUP_BREATHER_HUB, mtrap_set(), one_in(), place_spawns(), rl_dist(), rng(), rough_circle(), rough_circle_furn(), set_radiation(), spawn_item(), t_dirt, tr_drain, tr_glow, tr_hum, tr_shadow, tr_snake, tripoint::xy(), and tripoint::z.

Referenced by create_anomaly(), debug_menu::debug(), draw_lab(), and MapExtras::mx_portal_in().

◆ create_burnproducts()

void map::create_burnproducts ( const tripoint p,
const item fuel,
const units::mass burned_mass 
)

Definition at line 96 of file map_field.cpp.

97{
98 std::vector<material_id> all_mats = fuel.made_of();
99 if( all_mats.empty() ) {
100 return;
101 }
102 // Items that are multiple materials are assumed to be equal parts each.
103 const units::mass by_weight = burned_mass / all_mats.size();
104 for( material_id &mat : all_mats ) {
105 for( auto &bp : mat->burn_products() ) {
106 itype_id id = bp.first;
107 // Spawning the same item as the one that was just burned is pointless
108 // and leads to infinite recursion.
109 if( fuel.typeId() == id ) {
110 continue;
111 }
112 const float eff = bp.second;
113 const int n = std::floor( eff * ( by_weight / id->weight ) );
114
115 if( n <= 0 ) {
116 continue;
117 }
118 spawn_item( p, id, n, 1, calendar::turn );
119 }
120 }
121}
const std::string id
Definition: basecamp.h:87

References base_camps::id, item::made_of(), spawn_item(), calendar::turn, and item::typeId().

Referenced by MapExtras::burned_ground_parser(), and process_fields_in_submap().

◆ create_hot_air()

void map::create_hot_air ( const tripoint p,
int  intensity 
)
private

Definition at line 363 of file map_field.cpp.

364{
365 field_type_id hot_air;
366 switch( intensity ) {
367 case 1:
368 hot_air = fd_hot_air1;
369 break;
370 case 2:
371 hot_air = fd_hot_air2;
372 break;
373 case 3:
374 hot_air = fd_hot_air3;
375 break;
376 case 4:
377 hot_air = fd_hot_air4;
378 break;
379 default:
380 debugmsg( "Tried to spread hot air with intensity %d", intensity );
381 return;
382 }
383
384 for( int counter = 0; counter < 5; counter++ ) {
385 tripoint dst( p + point( rng( -1, 1 ), rng( -1, 1 ) ) );
386 add_field( dst, hot_air, 1 );
387 }
388}
field_type_id fd_hot_air3
Definition: field_type.cpp:381
field_type_id fd_hot_air2
Definition: field_type.cpp:380
field_type_id fd_hot_air1
Definition: field_type.cpp:379
field_type_id fd_hot_air4
Definition: field_type.cpp:382

References add_field(), debugmsg, fd_hot_air1, fd_hot_air2, fd_hot_air3, fd_hot_air4, and rng().

Referenced by process_fields_in_submap().

◆ creature_in_field()

void map::creature_in_field ( Creature critter)

Apply field effects to the creature when it's on a square with fields.

Definition at line 1563 of file map_field.cpp.

1564{
1565 bool in_vehicle = false;
1566 bool inside_vehicle = false;
1567 player *u = critter.as_player();
1568 if( critter.is_monster() ) {
1569 monster_in_field( *static_cast<monster *>( &critter ) );
1570 } else {
1571 if( u ) {
1572 in_vehicle = u->in_vehicle;
1573 // If we are in a vehicle figure out if we are inside (reduces effects usually)
1574 // and what part of the vehicle we need to deal with.
1575 if( in_vehicle ) {
1576 if( const optional_vpart_position vp = veh_at( u->pos() ) ) {
1577 if( vp->is_inside() ) {
1578 inside_vehicle = true;
1579 }
1580 }
1581 }
1582 player_in_field( *u );
1583 }
1584 }
1585
1586 field &curfield = get_field( critter.pos() );
1587 for( auto &field_entry_it : curfield ) {
1588 field_entry &cur_field_entry = field_entry_it.second;
1589 if( !cur_field_entry.is_field_alive() ) {
1590 continue;
1591 }
1592 const field_type_id cur_field_id = cur_field_entry.get_field_type();
1593
1594 for( const auto &fe : cur_field_entry.field_effects() ) {
1595 if( in_vehicle && fe.immune_in_vehicle ) {
1596 continue;
1597 }
1598 if( inside_vehicle && fe.immune_inside_vehicle ) {
1599 continue;
1600 }
1601 if( !inside_vehicle && fe.immune_outside_vehicle ) {
1602 continue;
1603 }
1604 if( in_vehicle && !one_in( fe.chance_in_vehicle ) ) {
1605 continue;
1606 }
1607 if( inside_vehicle && !one_in( fe.chance_inside_vehicle ) ) {
1608 continue;
1609 }
1610 if( !inside_vehicle && !one_in( fe.chance_outside_vehicle ) ) {
1611 continue;
1612 }
1613
1614 const effect field_fx = fe.get_effect();
1615 if( critter.is_immune_field( cur_field_id ) || critter.is_immune_effect( field_fx.get_id() ) ) {
1616 continue;
1617 }
1618 bool effect_added = false;
1619 if( fe.is_environmental ) {
1620 effect_added = critter.add_env_effect( fe.id, fe.bp->token, fe.intensity, fe.get_duration() );
1621 } else {
1622 effect_added = true;
1623 critter.add_effect( field_fx );
1624 }
1625 if( effect_added ) {
1626 critter.add_msg_player_or_npc( fe.env_message_type, fe.get_message(), fe.get_message_npc() );
1627 }
1628 }
1629 }
1630}
bool in_vehicle
Definition: character.h:1511
virtual bool is_monster() const
Definition: creature.h:101
virtual bool is_immune_field(const field_type_id &) const
Returns true if we are immune to the field type with the given fid.
Definition: creature.h:325
virtual void add_msg_player_or_npc(const std::string &, const std::string &) const
Definition: creature.h:677
virtual player * as_player()
Definition: creature.h:122
virtual bool is_immune_effect(const efftype_id &type) const =0
Definition: effect.h:161
const efftype_id & get_id() const
Returns the effect's matching effect_type id.
Definition: effect.h:305
std::vector< field_effect > field_effects() const
Definition: field.cpp:294
bool is_field_alive()
Definition: field.h:89
field_type_id get_field_type() const
Definition: field.cpp:105
A variable sized collection of field entries on a given map square.
Definition: field.h:131
void player_in_field(player &u)
Definition: map_field.cpp:1224
void monster_in_field(monster &z)
Definition: map_field.cpp:1632

References Creature::add_effect(), Creature::add_env_effect(), Creature::add_msg_player_or_npc(), Creature::as_player(), field_entry::field_effects(), get_field(), field_entry::get_field_type(), effect::get_id(), Character::in_vehicle, field_entry::is_field_alive(), Creature::is_immune_effect(), Creature::is_immune_field(), Creature::is_monster(), monster_in_field(), one_in(), player_in_field(), Creature::pos(), Character::pos(), and veh_at().

Referenced by add_field(), game::do_turn(), game::monmove(), npc::move_to(), and game::place_player().

◆ creature_on_trap()

void map::creature_on_trap ( Creature critter,
bool  may_avoid = true 
)

Apply trap effects to the creature, similar to creature_in_field.

If there is no trap at the creatures location, nothing is done. If the creature can avoid the trap, nothing is done as well. Otherwise the trap is triggered.

Parameters
critterCreature that just got trapped
may_avoidIf true, the creature tries to avoid the trap (Creature::avoid_trap). If false, the trap is always triggered.

Definition at line 8484 of file map.cpp.

8485{
8486 const auto &tr = tr_at( c.pos() );
8487 if( tr.is_null() ) {
8488 return;
8489 }
8490 // boarded in a vehicle means the player is above the trap, like a flying monster and can
8491 // never trigger the trap.
8492 const player *const p = dynamic_cast<const player *>( &c );
8493 if( p != nullptr && p->in_vehicle ) {
8494 return;
8495 }
8496 if( may_avoid && c.avoid_trap( c.pos(), tr ) ) {
8497 return;
8498 }
8499 tr.trigger( c.pos(), &c );
8500}

References c, Character::in_vehicle, and tr_at().

Referenced by game::fling_creature(), iexamine::ledge(), npc::move_to(), game::phasing_move(), game::place_player(), mattack::ranged_pull(), smash(), and game::vertical_move().

◆ crush()

void map::crush ( const tripoint p)

Definition at line 3672 of file map.cpp.

3673{
3674 player *crushed_player = g->critter_at<player>( p );
3675
3676 if( crushed_player != nullptr ) {
3677 bool player_inside = false;
3678 if( crushed_player->in_vehicle ) {
3679 const optional_vpart_position vp = veh_at( p );
3680 player_inside = vp && vp->is_inside();
3681 }
3682 if( !player_inside ) { //If there's a player at p and he's not in a covered vehicle...
3683 //This is the roof coming down on top of us, no chance to dodge
3684 crushed_player->add_msg_player_or_npc( m_bad, _( "You are crushed by the falling debris!" ),
3685 _( "<npcname> is crushed by the falling debris!" ) );
3686 // TODO: Make this depend on the ceiling material
3687 const int dam = rng( 0, 40 );
3688 // Torso and head take the brunt of the blow
3689 crushed_player->deal_damage( nullptr, bodypart_id( "head" ), damage_instance( DT_BASH,
3690 dam * .25 ) );
3691 crushed_player->deal_damage( nullptr, bodypart_id( "torso" ), damage_instance( DT_BASH,
3692 dam * .45 ) );
3693 // Legs take the next most through transferred force
3694 crushed_player->deal_damage( nullptr, bodypart_id( "leg_l" ), damage_instance( DT_BASH,
3695 dam * .10 ) );
3696 crushed_player->deal_damage( nullptr, bodypart_id( "leg_r" ), damage_instance( DT_BASH,
3697 dam * .10 ) );
3698 // Arms take the least
3699 crushed_player->deal_damage( nullptr, bodypart_id( "arm_l" ), damage_instance( DT_BASH,
3700 dam * .05 ) );
3701 crushed_player->deal_damage( nullptr, bodypart_id( "arm_r" ), damage_instance( DT_BASH,
3702 dam * .05 ) );
3703
3704 // Pin whoever got hit
3705 crushed_player->add_effect( effect_crushed, 1_turns, num_bp );
3706 crushed_player->check_dead_state();
3707 }
3708 }
3709
3710 if( monster *const monhit = g->critter_at<monster>( p ) ) {
3711 // 25 ~= 60 * .45 (torso)
3712 monhit->deal_damage( nullptr, bodypart_id( "torso" ), damage_instance( DT_BASH, rng( 0, 25 ) ) );
3713
3714 // Pin whoever got hit
3715 monhit->add_effect( effect_crushed, 1_turns, num_bp );
3716 monhit->check_dead_state();
3717 }
3718
3719 if( const optional_vpart_position vp = veh_at( p ) ) {
3720 // Arbitrary number is better than collapsing house roof crushing APCs
3721 vp->vehicle().damage( vp->part_index(), rng( 100, 1000 ), DT_BASH, false );
3722 }
3723}
int_id< body_part_type > bodypart_id
Definition: bodypart.h:23
@ num_bp
Definition: bodypart.h:52
void check_dead_state()
This function checks the creatures is_dead_state and (if true) calls die.
Definition: creature.cpp:1839
void add_msg_player_or_npc(const std::string &player_msg, const std::string &npc_str) const override
Definition: player.cpp:3978
@ m_bad
Definition: enums.h:261
static const efftype_id effect_crushed("crushed")

References _, Creature::add_effect(), player::add_msg_player_or_npc(), Creature::check_dead_state(), Character::deal_damage(), DT_BASH, effect_crushed, g, Character::in_vehicle, m_bad, num_bp, rng(), and veh_at().

Referenced by collapse_at().

◆ dangerous_field_at()

bool map::dangerous_field_at ( const tripoint p)

Definition at line 5397 of file map.cpp.

5398{
5399 for( auto &pr : field_at( p ) ) {
5400 auto &fd = pr.second;
5401 if( fd.is_dangerous() ) {
5402 return true;
5403 }
5404 }
5405 return false;
5406}
const field & field_at(const tripoint &p) const
Get the fields that are here.
Definition: map.cpp:5299

References field_at().

Referenced by are_requirements_nearby(), and generic_multi_activity_locations().

◆ decay_cosmetic_fields()

void map::decay_cosmetic_fields ( const tripoint p,
const time_duration time_since_last_actualize 
)
protected

Definition at line 7399 of file map.cpp.

7401{
7402 for( auto &pr : field_at( p ) ) {
7403 auto &fd = pr.second;
7404 const time_duration hl = fd.get_field_type().obj().half_life;
7405 if( !fd.decays_on_actualize() || hl <= 0_turns ) {
7406 continue;
7407 }
7408
7409 const time_duration added_age = 2 * time_since_last_actualize / rng( 2, 4 );
7410 fd.mod_field_age( added_age );
7411 const int intensity_drop = fd.get_field_age() / hl;
7412 if( intensity_drop > 0 ) {
7413 fd.set_field_intensity( fd.get_field_intensity() - intensity_drop );
7414 fd.mod_field_age( -hl * intensity_drop );
7415 }
7416 }
7417}

References field_at(), and rng().

Referenced by actualize().

◆ decay_fields_and_scent()

void map::decay_fields_and_scent ( const time_duration amount)

Moved here from weather.cpp for speed.

Decays fire, washable fields and scent. Washable fields are decayed only by 1/3 of the amount fire is.

Definition at line 2674 of file map.cpp.

2675{
2676 // TODO: Make this happen on all z-levels
2677
2678 // Decay scent separately, so that later we can use field count to skip empty submaps
2679 g->scent.decay();
2680
2681 // Coordinate code copied from lightmap calculations
2682 // TODO: Z
2683 const int smz = abs_sub.z;
2684 const auto &outside_cache = get_cache_ref( smz ).outside_cache;
2685 for( int smx = 0; smx < my_MAPSIZE; ++smx ) {
2686 for( int smy = 0; smy < my_MAPSIZE; ++smy ) {
2687 const auto cur_submap = get_submap_at_grid( { smx, smy, smz } );
2688 int to_proc = cur_submap->field_count;
2689 if( to_proc < 1 ) {
2690 if( to_proc < 0 ) {
2691 cur_submap->field_count = 0;
2692 dbg( DL::Error ) << "map::decay_fields_and_scent: submap at "
2693 << ( abs_sub + tripoint( smx, smy, 0 ) )
2694 << "has " << to_proc << " field_count";
2695 }
2696 get_cache( smz ).field_cache.reset( smx + ( smy * MAPSIZE ) );
2697 // This submap has no fields
2698 continue;
2699 }
2700
2701 for( int sx = 0; sx < SEEX; ++sx ) {
2702 if( to_proc < 1 ) {
2703 // This submap had some fields, but all got proc'd already
2704 break;
2705 }
2706
2707 for( int sy = 0; sy < SEEY; ++sy ) {
2708 const int x = sx + smx * SEEX;
2709 const int y = sy + smy * SEEY;
2710
2711 field &fields = cur_submap->get_field( { sx, sy} );
2712 if( !outside_cache[x][y] ) {
2713 to_proc -= fields.field_count();
2714 continue;
2715 }
2716
2717 for( auto &fp : fields ) {
2718 to_proc--;
2719 field_entry &cur = fp.second;
2720 const field_type_id type = cur.get_field_type();
2721 const int decay_amount_factor = type.obj().decay_amount_factor;
2722 if( decay_amount_factor != 0 ) {
2723 const time_duration decay_amount = amount / decay_amount_factor;
2724 cur.set_field_age( cur.get_field_age() + decay_amount );
2725 }
2726 }
2727 }
2728 }
2729
2730 if( to_proc > 0 ) {
2731 cur_submap->field_count = cur_submap->field_count - to_proc;
2732 dbg( DL::Error ) << "map::decay_fields_and_scent: submap at "
2733 << abs_sub + tripoint( smx, smy, 0 )
2734 << "has " << cur_submap->field_count - to_proc << "fields, but "
2735 << cur_submap->field_count << " field_count";
2736 }
2737 }
2738 }
2739}
time_duration set_field_age(const time_duration &new_age)
Sets age to the given value.
Definition: field.cpp:138
time_duration get_field_age() const
Definition: field.cpp:133
@ Error
Error (default: enabled).

References abs_sub, dbg, Error, level_cache::field_cache, submap::field_count, g, get_cache(), get_cache_ref(), field_entry::get_field_age(), field_entry::get_field_type(), get_submap_at_grid(), MAPSIZE, my_MAPSIZE, level_cache::outside_cache, SEEX, SEEY, field_entry::set_field_age(), sx, sy, type, and tripoint::z.

◆ delete_graffiti()

void map::delete_graffiti ( const tripoint p)

Definition at line 7825 of file map.cpp.

7826{
7827 if( !inbounds( p ) ) {
7828 return;
7829 }
7830 point l;
7831 submap *const current_submap = get_submap_at( p, l );
7832 current_submap->delete_graffiti( l );
7833}
void delete_graffiti(const point &p)
Definition: submap.cpp:109

References submap::delete_graffiti(), get_submap_at(), and inbounds().

◆ delete_signage()

void map::delete_signage ( const tripoint p) const

Definition at line 4022 of file map.cpp.

4023{
4024 if( !inbounds( p ) ) {
4025 return;
4026 }
4027
4028 point l;
4029 submap *const current_submap = get_submap_at( p, l );
4030
4031 current_submap->delete_signage( l );
4032}
void delete_signage(const point &p)
Definition: submap.cpp:148

References submap::delete_signage(), get_submap_at(), and inbounds().

Referenced by bash_furn_success(), construct::done_deconstruct(), and talk_function::loot_building().

◆ deregister_vehicle_zone()

bool map::deregister_vehicle_zone ( zone_data zone)

Definition at line 963 of file map.cpp.

964{
966 zone.get_start_point() ) ).part_with_feature( "CARGO", false ) ) {
967 auto bounds = vp->vehicle().loot_zones.equal_range( vp->mount() );
968 for( auto it = bounds.first; it != bounds.second; it++ ) {
969 if( &zone == &( it->second ) ) {
970 vp->vehicle().loot_zones.erase( it );
971 return true;
972 }
973 }
974 }
975 return false;
976}
tripoint getlocal(const tripoint &p) const
Inverse of getabs.
Definition: map.cpp:8278
tripoint get_start_point() const
Definition: clzones.h:314

References zone_data::get_start_point(), getlocal(), optional_vpart_position::part_with_feature(), and veh_at().

◆ destroy()

void map::destroy ( const tripoint p,
bool  silent = false 
)

Keeps bashing a square until it can't be bashed anymore.

Definition at line 3638 of file map.cpp.

3639{
3640 // Break if it takes more than 25 destructions to remove to prevent infinite loops
3641 // Example: A bashes to B, B bashes to A leads to A->B->A->...
3642
3643 // If we were destroying a floor, allow destroying floors
3644 // If we were destroying something unpassable, destroy only that
3645 bool was_impassable = impassable( p );
3646 int count = 0;
3647 while( count <= 25
3648 && bash( p, 999, silent, true ).success
3649 && ( !was_impassable || impassable( p ) ) ) {
3650 count++;
3651 }
3652}

References bash(), detail::count(), impassable(), silent, and behavior::success.

Referenced by add_vehicle_to_map(), bash(), MapExtras::burned_ground_parser(), activity_handlers::burrow_finish(), collapse_at(), draw_lab(), activity_handlers::jackhammer_finish(), make_rubble(), MapExtras::mx_crater(), MapExtras::mx_helicopter(), MapExtras::mx_supplydrop(), om_cutdown_trees(), activity_handlers::pickaxe_finish(), process_fields_in_submap(), and explosion_handler::explosion_funcs::resonance_cascade().

◆ destroy_furn()

void map::destroy_furn ( const tripoint p,
bool  silent = false 
)

Keeps bashing a square until there is no more furniture.

Definition at line 3654 of file map.cpp.

3655{
3656 // Break if it takes more than 25 destructions to remove to prevent infinite loops
3657 // Example: A bashes to B, B bashes to A leads to A->B->A->...
3658 int count = 0;
3659 while( count <= 25 && furn( p ) != f_null && bash( p, 999, silent, true ).success ) {
3660 count++;
3661 }
3662}

References bash(), detail::count(), f_null, furn(), silent, and behavior::success.

Referenced by construct::done_grave(), and make_rubble().

◆ destroy_vehicle()

◆ detach_vehicle()

std::unique_ptr< vehicle > map::detach_vehicle ( vehicle veh)

Definition at line 354 of file map.cpp.

355{
356 if( veh == nullptr ) {
357 debugmsg( "map::detach_vehicle was passed nullptr" );
358 return std::unique_ptr<vehicle>();
359 }
360
361 int z = veh->sm_pos.z;
362 if( z < -OVERMAP_DEPTH || z > OVERMAP_HEIGHT ) {
363 debugmsg( "detach_vehicle got a vehicle outside allowed z-level range! name=%s, submap:%d,%d,%d",
364 veh->name, veh->sm_pos.x, veh->sm_pos.y, veh->sm_pos.z );
365 // Try to fix by moving the vehicle here
366 z = veh->sm_pos.z = abs_sub.z;
367 }
368
369 // Unboard all passengers before detaching
370 for( auto const &part : veh->get_avail_parts( VPFLAG_BOARDABLE ) ) {
371 player *passenger = part.get_passenger();
372 if( passenger ) {
373 unboard_vehicle( part, passenger );
374 }
375 }
376 veh->invalidate_towing( true );
377 submap *const current_submap = get_submap_at_grid( veh->sm_pos );
378 level_cache &ch = get_cache( z );
379 for( size_t i = 0; i < current_submap->vehicles.size(); i++ ) {
380 if( current_submap->vehicles[i].get() == veh ) {
381 ch.vehicle_list.erase( veh );
382 ch.zone_vehicles.erase( veh );
384 std::unique_ptr<vehicle> result = std::move( current_submap->vehicles[i] );
385 current_submap->vehicles.erase( current_submap->vehicles.begin() + i );
386 if( veh->tracking_on ) {
388 }
389 dirty_vehicle_list.erase( veh );
390 veh->detach();
391 veh->refresh_position();
392 return result;
393 }
394 }
395 debugmsg( "detach_vehicle can't find it! name=%s, submap:%d,%d,%d", veh->name, veh->sm_pos.x,
396 veh->sm_pos.y, veh->sm_pos.z );
397 return std::unique_ptr<vehicle>();
398}
std::set< vehicle * > dirty_vehicle_list
Definition: map.h:1647
void reset_vehicle_cache()
Definition: map.cpp:254
void remove_vehicle(const vehicle *veh)
Remove the vehicle from being tracked in the overmap.
std::string name
Definition: vehicle.h:1849
void refresh_position()
Definition: vehicle.cpp:5815
bool tracking_on
Definition: vehicle.h:1991
void invalidate_towing(bool first_vehicle=false)
Definition: vehicle.cpp:6129
void detach()
Definition: vehicle.h:768
std::set< vehicle * > zone_vehicles
Definition: map.h:358
std::set< vehicle * > vehicle_list
Definition: map.h:357

References abs_sub, debugmsg, vehicle::detach(), dirty_vehicle_list, vehicle::get_avail_parts(), get_cache(), get_submap_at_grid(), vehicle::invalidate_towing(), avatar_action::move(), vehicle::name, overmap_buffer, OVERMAP_HEIGHT, vehicle::refresh_position(), overmapbuffer::remove_vehicle(), reset_vehicle_cache(), vehicle::sm_pos, vehicle::tracking_on, unboard_vehicle(), level_cache::vehicle_list, submap::vehicles, VPFLAG_BOARDABLE, tripoint::x, tripoint::y, tripoint::z, and level_cache::zone_vehicles.

Referenced by add_vehicle_to_map(), destroy_vehicle(), and editmap::mapgen_veh_destroy().

◆ determine_wall_corner()

int map::determine_wall_corner ( const tripoint p) const
private

Definition at line 7856 of file map.cpp.

7857{
7858 int test_connect_group = ter( p ).obj().connect_group;
7859 uint8_t connections = get_known_connections( p, test_connect_group );
7860 // The bits in connections are SEWN, whereas the characters in LINE_
7861 // constants are NESW, so we want values in 8 | 2 | 1 | 4 order.
7862 switch( connections ) {
7863 case 8 | 2 | 1 | 4:
7864 return LINE_XXXX;
7865 case 0 | 2 | 1 | 4:
7866 return LINE_OXXX;
7867
7868 case 8 | 0 | 1 | 4:
7869 return LINE_XOXX;
7870 case 0 | 0 | 1 | 4:
7871 return LINE_OOXX;
7872
7873 case 8 | 2 | 0 | 4:
7874 return LINE_XXOX;
7875 case 0 | 2 | 0 | 4:
7876 return LINE_OXOX;
7877 case 8 | 0 | 0 | 4:
7878 return LINE_XOOX;
7879 case 0 | 0 | 0 | 4:
7880 return LINE_OXOX; // LINE_OOOX would be better
7881
7882 case 8 | 2 | 1 | 0:
7883 return LINE_XXXO;
7884 case 0 | 2 | 1 | 0:
7885 return LINE_OXXO;
7886 case 8 | 0 | 1 | 0:
7887 return LINE_XOXO;
7888 case 0 | 0 | 1 | 0:
7889 return LINE_XOXO; // LINE_OOXO would be better
7890 case 8 | 2 | 0 | 0:
7891 return LINE_XXOO;
7892 case 0 | 2 | 0 | 0:
7893 return LINE_OXOX; // LINE_OXOO would be better
7894 case 8 | 0 | 0 | 0:
7895 return LINE_XOXO; // LINE_XOOO would be better
7896
7897 case 0 | 0 | 0 | 0:
7898 return ter( p ).obj().symbol(); // technically just a column
7899
7900 default:
7901 // assert( false );
7902 // this shall not happen
7903 return '?';
7904 }
7905}
uint8_t get_known_connections(const tripoint &p, int connect_group, const std::map< tripoint, ter_id > &override={}) const
Definition: map.cpp:1510
generic_factory< overmap_connection > connections("overmap connection")
#define LINE_XOXX
Definition: output.h:47
#define LINE_XOXO
Definition: output.h:39
#define LINE_OXOX
Definition: output.h:40
#define LINE_OOXX
Definition: output.h:43
#define LINE_OXXX
Definition: output.h:48
#define LINE_XXXO
Definition: output.h:45
#define LINE_XXOX
Definition: output.h:46
#define LINE_OXXO
Definition: output.h:42
#define LINE_XOOX
Definition: output.h:44
#define LINE_XXOO
Definition: output.h:41
#define LINE_XXXX
Definition: output.h:49
int symbol() const
Definition: mapdata.cpp:550

References map_data_common_t::connect_group, anonymous_namespace{overmap_connection.cpp}::connections, get_known_connections(), LINE_OOXX, LINE_OXOX, LINE_OXXO, LINE_OXXX, LINE_XOOX, LINE_XOXO, LINE_XOXX, LINE_XXOO, LINE_XXOX, LINE_XXXO, LINE_XXXX, int_id< T >::obj(), map_data_common_t::symbol(), and ter().

Referenced by draw_from_above(), and draw_maptile().

◆ disarm_trap()

void map::disarm_trap ( const tripoint p)
Perception increases chance of disarming trap Dexterity increases chance of disarming trap Traps increases chance of disarming trap

Definition at line 5215 of file map.cpp.

5216{
5217 const trap &tr = tr_at( p );
5218 if( tr.is_null() ) {
5219 debugmsg( "Tried to disarm a trap where there was none (%d %d %d)", p.x, p.y, p.z );
5220 return;
5221 }
5222
5223 const int tSkillLevel = g->u.get_skill_level( skill_traps );
5224 const int diff = tr.get_difficulty();
5225 int roll = rng( tSkillLevel, 4 * tSkillLevel );
5226
5227 // Some traps are not actual traps. Skip the rolls, different message and give the option to grab it right away.
5228 if( tr.get_avoidance() == 0 && tr.get_difficulty() == 0 ) {
5229 add_msg( _( "The %s is taken down." ), tr.name() );
5230 tr.on_disarmed( *this, p );
5231 return;
5232 }
5233
5234 ///\EFFECT_PER increases chance of disarming trap
5235
5236 ///\EFFECT_DEX increases chance of disarming trap
5237
5238 ///\EFFECT_TRAPS increases chance of disarming trap
5239 while( ( rng( 5, 20 ) < g->u.per_cur || rng( 1, 20 ) < g->u.dex_cur ) && roll < 50 ) {
5240 roll++;
5241 }
5242 if( roll >= diff ) {
5243 add_msg( _( "You disarm the trap!" ) );
5244 const int morale_buff = tr.get_avoidance() * 0.4 + tr.get_difficulty() + rng( 0, 4 );
5245 g->u.rem_morale( MORALE_FAILURE );
5246 g->u.add_morale( MORALE_ACCOMPLISHMENT, morale_buff, 40 );
5247 tr.on_disarmed( *this, p );
5248 if( diff > 1.25 * tSkillLevel ) { // failure might have set off trap
5249 g->u.practice( skill_traps, 1.5 * ( diff - tSkillLevel ) );
5250 }
5251 } else if( roll >= diff * .8 ) {
5252 add_msg( _( "You fail to disarm the trap." ) );
5253 const int morale_debuff = -rng( 6, 18 );
5254 g->u.rem_morale( MORALE_ACCOMPLISHMENT );
5255 g->u.add_morale( MORALE_FAILURE, morale_debuff, -40 );
5256 if( diff > 1.25 * tSkillLevel ) {
5257 g->u.practice( skill_traps, 1.5 * ( diff - tSkillLevel ) );
5258 }
5259 } else {
5260 add_msg( m_bad, _( "You fail to disarm the trap, and you set it off!" ) );
5261 const int morale_debuff = -rng( 12, 24 );
5262 g->u.rem_morale( MORALE_ACCOMPLISHMENT );
5263 g->u.add_morale( MORALE_FAILURE, morale_debuff, -40 );
5264 tr.trigger( p, &g->u );
5265 if( diff - roll <= 6 ) {
5266 // Give xp for failing, but not if we failed terribly (in which
5267 // case the trap may not be disarmable).
5268 g->u.practice( skill_traps, 2 * diff );
5269 }
5270 }
5271}
static const skill_id skill_traps("traps")
void add_msg(std::string msg)
Definition: messages.cpp:884
const morale_type MORALE_FAILURE("morale_failure")
const morale_type MORALE_ACCOMPLISHMENT("morale_accomplishment")
Definition: trap.h:86
std::string name() const
Definition: trap.cpp:177
int get_avoidance() const
Whether triggering the trap can be avoid (if greater than 0) and if so, this is compared to dodge ski...
Definition: trap.h:144
void trigger(const tripoint &pos, Creature *creature=nullptr, item *item=nullptr) const
Trigger trap effects.
Definition: trap.cpp:232
bool is_null() const
Whether this is the null-traps, aka no trap at all.
Definition: trap.cpp:245
void on_disarmed(map &m, const tripoint &p) const
Called when a trap at the given point in the map has been disarmed.
Definition: trap.cpp:260
int get_difficulty() const
This is used when disarming the trap.
Definition: trap.h:152

References _, add_msg(), debugmsg, g, trap::get_avoidance(), trap::get_difficulty(), trap::is_null(), m_bad, MORALE_ACCOMPLISHMENT, MORALE_FAILURE, trap::name(), trap::on_disarmed(), rng(), skill_traps, tr_at(), trap::trigger(), tripoint::x, tripoint::y, and tripoint::z.

Referenced by iexamine::trap().

◆ disp_name()

std::string map::disp_name ( const tripoint p)

Definition at line 1330 of file map.cpp.

1331{
1332 return string_format( _( "the %s" ), name( p ) );
1333}

References _, name(), and string_format().

Referenced by vehicle::part_collision().

◆ displace_vehicle()

bool map::displace_vehicle ( vehicle veh,
const tripoint dp 
)

Definition at line 1119 of file map.cpp.

1120{
1121 const tripoint src = veh.global_pos3();
1122
1123 tripoint dst = src + dp;
1124
1125 if( !inbounds( src ) ) {
1126 add_msg( m_debug, "map::displace_vehicle: coordinates out of bounds %d,%d,%d->%d,%d,%d",
1127 src.x, src.y, src.z, dst.x, dst.y, dst.z );
1128 return false;
1129 }
1130
1131 point src_offset;
1132 point dst_offset;
1133 submap *src_submap = get_submap_at( src, src_offset );
1134 submap *dst_submap = get_submap_at( dst, dst_offset );
1135 std::set<int> smzs;
1136
1137 // first, let's find our position in current vehicles vector
1138 size_t our_i = 0;
1139 bool found = false;
1140 for( auto &smap : grid ) {
1141 for( size_t i = 0; i < smap->vehicles.size(); i++ ) {
1142 if( smap->vehicles[i].get() == &veh ) {
1143 our_i = i;
1144 src_submap = smap;
1145 found = true;
1146 break;
1147 }
1148 }
1149 if( found ) {
1150 break;
1151 }
1152 }
1153
1154 if( !found ) {
1155 add_msg( m_debug, "displace_vehicle [%s] failed", veh.name );
1156 return false;
1157 }
1158
1159 // move the vehicle
1160 // don't let it go off grid
1161 if( !inbounds( dst ) ) {
1162 veh.stop();
1163 // Silent debug
1164 dbg( DL::Error ) << "map:displace_vehicle: Stopping vehicle, displaced dp=" << dp;
1165 return true;
1166 }
1167
1168 // Need old coordinates to check for remote control
1169 const bool remote = veh.remote_controlled( g->u );
1170
1171 // record every passenger and pet inside
1172 std::vector<rider_data> riders = veh.get_riders();
1173
1174 bool need_update = false;
1175 bool z_change = false;
1176 int z_to = 0;
1177 // Move passengers and pets
1178 bool complete = false;
1179 // loop until everyone has moved or for each passenger
1180 for( size_t i = 0; !complete && i < riders.size(); i++ ) {
1181 complete = true;
1182 for( rider_data &r : riders ) {
1183 if( r.moved ) {
1184 continue;
1185 }
1186 const int prt = r.prt;
1187
1188 Creature *psg = r.psg;
1189 const tripoint part_pos = veh.global_part_pos3( prt );
1190 if( psg == nullptr ) {
1191 debugmsg( "Empty passenger for part #%d at %d,%d,%d player at %d,%d,%d?",
1192 prt, part_pos.x, part_pos.y, part_pos.z,
1193 g->u.posx(), g->u.posy(), g->u.posz() );
1195 r.moved = true;
1196 continue;
1197 }
1198
1199 if( psg->pos() != part_pos ) {
1200 add_msg( m_debug, "Part/passenger position mismatch: part #%d at %d,%d,%d "
1201 "passenger at %d,%d,%d", prt, part_pos.x, part_pos.y, part_pos.z,
1202 psg->posx(), psg->posy(), psg->posz() );
1203 }
1204 const vehicle_part &veh_part = veh.part( prt );
1205
1206 tripoint next_pos = veh_part.precalc[1];
1207
1208 // Place passenger on the new part location
1209 tripoint psgp( dst + next_pos );
1210 // someone is in the way so try again
1211 if( g->critter_at( psgp ) ) {
1212 complete = false;
1213 continue;
1214 }
1215 if( psg->is_avatar() ) {
1216 // If passenger is you, we need to update the map
1217 need_update = true;
1218 z_change = psgp.z != part_pos.z;
1219 z_to = psgp.z;
1220 }
1221
1222 psg->setpos( psgp );
1223 r.moved = true;
1224 }
1225 }
1226
1227 veh.shed_loose_parts();
1228 smzs = veh.advance_precalc_mounts( dst_offset, src );
1229 if( src_submap != dst_submap ) {
1230 veh.set_submap_moved( tripoint( dst.x / SEEX, dst.y / SEEY, dst.z ) );
1231 auto src_submap_veh_it = src_submap->vehicles.begin() + our_i;
1232 dst_submap->vehicles.push_back( std::move( *src_submap_veh_it ) );
1233 src_submap->vehicles.erase( src_submap_veh_it );
1234 dst_submap->is_uniform = false;
1236 }
1237 if( need_update ) {
1238 g->update_map( g->u );
1239 }
1240 add_vehicle_to_cache( &veh );
1241
1242 if( z_change || src.z != dst.z ) {
1243 if( z_change ) {
1244 g->vertical_shift( z_to );
1245 // vertical moves can flush the caches, so make sure we're still in the cache
1246 add_vehicle_to_cache( &veh );
1247 }
1248 update_vehicle_list( dst_submap, dst.z );
1249 // delete the vehicle from the source z-level vehicle cache set if it is no longer on
1250 // that z-level
1251 if( src.z != dst.z ) {
1252 level_cache &ch2 = get_cache( src.z );
1253 for( const vehicle *elem : ch2.vehicle_list ) {
1254 if( elem == &veh ) {
1255 ch2.vehicle_list.erase( &veh );
1256 ch2.zone_vehicles.erase( &veh );
1257 break;
1258 }
1259 }
1260 }
1262 }
1263
1264 if( remote ) {
1265 // Has to be after update_map or coordinates won't be valid
1266 g->setremoteveh( &veh );
1267 }
1268
1269 //
1270 //global positions of vehicle loot zones have changed.
1271 veh.zones_dirty = true;
1272
1273 for( int vsmz : smzs ) {
1274 on_vehicle_moved( dst.z + vsmz );
1275 }
1276 return true;
1277}
virtual int posy() const =0
virtual int posz() const =0
virtual void setpos(const tripoint &pos)=0
virtual bool is_avatar() const
Definition: creature.h:95
virtual int posx() const =0
void on_vehicle_moved(int smz)
Callback invoked when a vehicle has moved.
Definition: map.cpp:405
void update_vehicle_list(const submap *to, int zlev)
Definition: map.cpp:340
tripoint global_pos3() const
Definition: vehicle.cpp:3281
bool check_is_heli_landed()
void shed_loose_parts()
Definition: vehicle.cpp:6257
std::vector< rider_data > get_riders() const
Definition: vehicle.cpp:3238
void stop(bool update_cache=true)
std::set< int > advance_precalc_mounts(const point &new_pos, const tripoint &src)
Definition: vehicle.cpp:7095
bool remote_controlled(const Character &p) const
Definition: vehicle.cpp:297
void set_submap_moved(const tripoint &p)
Update the submap coordinates and update the tracker info in the overmap (if enabled).
Definition: vehicle.cpp:3296
bool zones_dirty
Definition: vehicle.h:2007
@ m_debug
Definition: enums.h:271
Structure, describing vehicle part (i.e., wheel, seat)
Definition: vehicle.h:185
std::array< tripoint, 2 > precalc
mount translated to face.dir [0] and turn_dir [1]
Definition: vehicle.h:371
int remove_flag(const int flag) noexcept
Definition: vehicle.h:214

References add_msg(), add_vehicle_to_cache(), vehicle::advance_precalc_mounts(), vehicle::check_is_heli_landed(), dbg, debugmsg, Error, g, get_cache(), vehicle::get_riders(), get_submap_at(), vehicle::global_part_pos3(), vehicle::global_pos3(), grid, inbounds(), invalidate_max_populated_zlev(), Creature::is_avatar(), submap::is_uniform, m_debug, avatar_action::move(), vehicle::name, on_vehicle_moved(), vehicle::part(), vehicle_part::passenger_flag, Creature::pos(), Creature::posx(), Creature::posy(), Creature::posz(), vehicle_part::precalc, vehicle::remote_controlled(), vehicle_part::remove_flag(), SEEX, SEEY, vehicle::set_submap_moved(), Creature::setpos(), vehicle::shed_loose_parts(), vehicle::stop(), update_vehicle_list(), level_cache::vehicle_list, submap::vehicles, tripoint::x, tripoint::y, tripoint::z, level_cache::zone_vehicles, and vehicle::zones_dirty.

Referenced by game::grabbed_veh_move(), and move_vehicle().

◆ displace_water()

bool map::displace_water ( const tripoint dp)

Definition at line 1279 of file map.cpp.

1280{
1281 // Check for shallow water
1282 if( has_flag( "SWIMMABLE", p ) && !has_flag( TFLAG_DEEP_WATER, p ) ) {
1283 int dis_places = 0;
1284 int sel_place = 0;
1285 for( int pass = 0; pass < 2; pass++ ) {
1286 // we do 2 passes.
1287 // first, count how many non-water places around
1288 // then choose one within count and fill it with water on second pass
1289 if( pass != 0 ) {
1290 sel_place = rng( 0, dis_places - 1 );
1291 dis_places = 0;
1292 }
1293 for( const tripoint &temp : points_in_radius( p, 1 ) ) {
1294 if( temp != p
1295 || impassable_ter_furn( temp )
1296 || has_flag( TFLAG_DEEP_WATER, temp ) ) {
1297 continue;
1298 }
1299 ter_id ter0 = ter( temp );
1300 if( ter0 == t_water_sh ||
1301 ter0 == t_water_dp || ter0 == t_water_moving_sh || ter0 == t_water_moving_dp ) {
1302 continue;
1303 }
1304 if( pass != 0 && dis_places == sel_place ) {
1305 ter_set( temp, t_water_sh );
1306 ter_set( temp, t_dirt );
1307 return true;
1308 }
1309
1310 dis_places++;
1311 }
1312 }
1313 }
1314 return false;
1315}
ter_id t_water_moving_dp
Definition: mapdata.cpp:693
ter_id t_water_moving_sh
Definition: mapdata.cpp:693
ter_id t_water_dp
Definition: mapdata.cpp:693
ter_id t_water_sh
Definition: mapdata.cpp:693

References has_flag(), impassable_ter_furn(), points_in_radius(), rng(), t_dirt, t_water_dp, t_water_moving_dp, t_water_moving_sh, t_water_sh, ter(), ter_set(), and TFLAG_DEEP_WATER.

Referenced by move_vehicle().

◆ do_vehicle_caching()

void map::do_vehicle_caching ( int  z)

Definition at line 8211 of file map.cpp.

8212{
8213 level_cache &ch = get_cache( z );
8214 for( vehicle *v : ch.vehicle_list ) {
8215 for( const vpart_reference &vp : v->get_all_parts() ) {
8216 const tripoint &part_pos = v->global_part_pos3( vp.part() );
8217 if( !inbounds( part_pos.xy() ) || vp.part().removed ) {
8218 continue;
8219 }
8220 vehicle_caching_internal( get_cache( part_pos.z ), vp, v );
8221 if( part_pos.z < OVERMAP_HEIGHT ) {
8222 vehicle_caching_internal_above( get_cache( part_pos.z + 1 ), vp, v );
8223 }
8224 }
8225 }
8226}
static void vehicle_caching_internal_above(level_cache &zch_above, const vpart_reference &vp, vehicle *v)
Definition: map.cpp:8202
static void vehicle_caching_internal(level_cache &zch, const vpart_reference &vp, vehicle *v)
Definition: map.cpp:8135

References vehicle::get_all_parts(), get_cache(), vehicle::global_part_pos3(), inbounds(), OVERMAP_HEIGHT, vehicle_caching_internal(), vehicle_caching_internal_above(), level_cache::vehicle_list, tripoint::xy(), and tripoint::z.

Referenced by build_map_cache().

◆ dont_draw_lower_floor()

bool map::dont_draw_lower_floor ( const tripoint p)

Definition at line 5871 of file map.cpp.

5872{
5873 return !zlevels || p.z <= -OVERMAP_DEPTH ||
5875}
@ TFLAG_Z_TRANSPARENT
Definition: mapdata.h:321

References has_flag(), OVERMAP_DEPTH, TFLAG_NO_FLOOR, TFLAG_Z_TRANSPARENT, tripoint::z, and zlevels.

◆ draw()

void map::draw ( const catacurses::window w,
const tripoint center 
)

Draw a visible part of the map into w.

This method uses g->u.posx()/posy() for visibility calculations, so it can not be used for anything but the player's viewport. Likewise, only g->m and maps with equivalent coordinates can be used, as other maps would have coordinate systems incompatible with g->u.posx()

Parameters
wWindow we are drawing in
centerThe coordinate of the center of the viewport, this can be different from the player coordinate.

Definition at line 5712 of file map.cpp.

5713{
5714 // We only need to draw anything if we're not in tiles mode.
5715 if( is_draw_tiles_mode() ) {
5716 return;
5717 }
5718
5719 g->reset_light_level();
5720
5723
5724 const auto &visibility_cache = get_cache_ref( center.z ).visibility_cache;
5725
5726 int wnd_h = getmaxy( w );
5727 int wnd_w = getmaxx( w );
5728 const tripoint offs = center - tripoint( wnd_w / 2, wnd_h / 2, 0 );
5729
5730 // Map memory should be at least the size of the view range
5731 // so that new tiles can be memorized, and at least the size of the terminal
5732 // since displayed area may be bigger than view range.
5733 const point min_mm_reg = point(
5734 std::min( 0, offs.x ),
5735 std::min( 0, offs.y )
5736 );
5737 const point max_mm_reg = point(
5738 std::max( MAPSIZE_X, offs.x + wnd_w ),
5739 std::max( MAPSIZE_Y, offs.y + wnd_h )
5740 );
5741 g->u.prepare_map_memory_region(
5742 g->m.getabs( tripoint( min_mm_reg, center.z ) ),
5743 g->m.getabs( tripoint( max_mm_reg, center.z ) )
5744 );
5745
5746 const auto draw_background = [&]( const tripoint & p ) {
5747 int sym = ' ';
5748 nc_color col = c_black;
5749 if( has_memory_at( p ) ) {
5750 sym = get_memory_at( p );
5751 col = c_brown;
5752 }
5753 wputch( w, col, sym );
5754 };
5755
5756 const auto draw_vision_effect = [&]( const visibility_type vis ) -> bool {
5757 int sym = '#';
5758 nc_color col;
5759 switch( vis )
5760 {
5761 case VIS_LIT:
5762 // can only tell that this square is bright
5763 col = c_light_gray;
5764 break;
5765 case VIS_BOOMER:
5766 col = c_pink;
5767 break;
5768 case VIS_BOOMER_DARK:
5769 col = c_magenta;
5770 break;
5771 default:
5772 return false;
5773 }
5774 wputch( w, col, sym );
5775 return true;
5776 };
5777
5778 drawsq_params params = drawsq_params().memorize( true );
5779 for( int wy = 0; wy < wnd_h; wy++ ) {
5780 for( int wx = 0; wx < wnd_w; wx++ ) {
5781 wmove( w, point( wx, wy ) );
5782 const tripoint p = offs + tripoint( wx, wy, 0 );
5783 if( !inbounds( p ) ) {
5784 draw_background( p );
5785 continue;
5786 }
5787
5788 const lit_level lighting = visibility_cache[p.x][p.y];
5789 const visibility_type vis = get_visibility( lighting, cache );
5790
5791 if( draw_vision_effect( vis ) ) {
5792 continue;
5793 }
5794
5795 if( vis == VIS_HIDDEN || vis == VIS_DARK ) {
5796 draw_background( p );
5797 continue;
5798 }
5799
5800 const maptile curr_maptile = maptile_at_internal( p );
5801 params
5802 .low_light( lighting == lit_level::LOW )
5803 .bright_light( lighting == lit_level::BRIGHT );
5804 if( draw_maptile( w, p, curr_maptile, params ) ) {
5805 continue;
5806 }
5807 const maptile tile_below = maptile_at_internal( p - tripoint_above );
5808 draw_from_above( w, tripoint( p.xy(), p.z - 1 ), tile_below, params );
5809 }
5810 }
5811
5812 // Memorize off-screen tiles
5813 half_open_rectangle<point> display( offs.xy(), offs.xy() + point( wnd_w, wnd_h ) );
5814 drawsq_params mm_params = drawsq_params().memorize( true ).output( false );
5815 for( int y = 0; y < MAPSIZE_Y; y++ ) {
5816 for( int x = 0; x < MAPSIZE_X; x++ ) {
5817 const tripoint p( x, y, center.z );
5818 if( display.contains( p.xy() ) ) {
5819 // Have been memorized during display loop
5820 continue;
5821 }
5822
5823 const lit_level lighting = visibility_cache[p.x][p.y];
5824 const visibility_type vis = get_visibility( lighting, cache );
5825
5826 if( vis != VIS_CLEAR ) {
5827 continue;
5828 }
5829
5830 const maptile curr_maptile = maptile_at_internal( p );
5831 mm_params
5832 .low_light( lighting == lit_level::LOW )
5833 .bright_light( lighting == lit_level::BRIGHT );
5834
5835 draw_maptile( w, p, curr_maptile, mm_params );
5836 }
5837 }
5838}
bool draw_maptile(const catacurses::window &w, const tripoint &p, const maptile &tile, const drawsq_params &params) const
Internal version of the drawsq.
Definition: map.cpp:5877
visibility_type get_visibility(lit_level ll, const visibility_variables &cache) const
Definition: map.cpp:5662
void draw_from_above(const catacurses::window &w, const tripoint &p, const maptile &tile, const drawsq_params &params) const
Draws the tile as seen from above.
Definition: map.cpp:6068
const visibility_variables & get_visibility_variables_cache() const
Definition: map.cpp:5657
void update_visibility_cache(int zlev)
Definition: map.cpp:5608
maptile maptile_at_internal(const tripoint &p) const
Definition: map.cpp:219
#define c_light_gray
Definition: color.h:19
#define c_black
Definition: color.h:17
#define c_magenta
Definition: color.h:25
#define c_brown
Definition: color.h:26
#define c_pink
Definition: color.h:31
visibility_type
Definition: enums.h:57
@ VIS_CLEAR
Definition: enums.h:59
@ VIS_BOOMER
Definition: enums.h:61
@ VIS_DARK
Definition: enums.h:62
@ VIS_BOOMER_DARK
Definition: enums.h:63
@ VIS_HIDDEN
Definition: enums.h:58
@ VIS_LIT
Definition: enums.h:60
lit_level
Definition: lightmap.h:43
static bool has_memory_at(const tripoint &p)
Definition: map.cpp:5695
static int get_memory_at(const tripoint &p)
Definition: map.cpp:5704
int getmaxx(const window &win)
Definition: ncurses_def.cpp:58
int getmaxy(const window &win)
Definition: ncurses_def.cpp:63
void wmove(const window &win, const point &p)
Definition: ncurses_def.cpp:98
static tripoint_abs_omt display(const tripoint_abs_omt &orig, const draw_data_t &data=draw_data_t())
bool is_draw_tiles_mode()
Check whether we're in tile drawing mode.
Definition: output.cpp:2029
void wputch(const catacurses::window &w, nc_color FG, int ch)
Definition: output.cpp:470
static constexpr tripoint tripoint_above
Definition: point.h:294
Draw parameters used by map::drawsq() and similar methods.
Definition: map.h:180
constexpr drawsq_params & bright_light(bool v)
Whether tile is in bright light.
Definition: map.h:240
constexpr drawsq_params & output(bool v)
HACK: Whether the tile should be printed.
Definition: map.h:269
constexpr drawsq_params & memorize(bool v)
Whether the tile should be memorized.
Definition: map.h:254
constexpr drawsq_params & low_light(bool v)
Whether tile is low light, and should be drawn with muted color.
Definition: map.h:226
lit_level visibility_cache[MAPSIZE_X][MAPSIZE_Y]
Definition: map.h:350
A wrapper for a submap point.
Definition: submap.h:267

References BRIGHT, drawsq_params::bright_light(), c_black, c_brown, c_light_gray, c_magenta, c_pink, center, overmap_ui::display(), draw_from_above(), draw_maptile(), g, get_cache_ref(), get_memory_at(), get_visibility(), get_visibility_variables_cache(), catacurses::getmaxx(), catacurses::getmaxy(), has_memory_at(), inbounds(), is_draw_tiles_mode(), LOW, drawsq_params::low_light(), MAPSIZE_X, MAPSIZE_Y, maptile_at_internal(), drawsq_params::memorize(), drawsq_params::output(), tripoint_above, update_visibility_cache(), VIS_BOOMER, VIS_BOOMER_DARK, VIS_CLEAR, VIS_DARK, VIS_HIDDEN, VIS_LIT, level_cache::visibility_cache, catacurses::wmove(), wputch(), tripoint::x, tripoint::xy(), tripoint::y, and tripoint::z.

Referenced by advanced_inventory::draw_minimap(), and game::draw_ter().

◆ draw_anthill()

void map::draw_anthill ( mapgendata dat)
protected

Definition at line 5032 of file mapgen.cpp.

5033{
5034 const oter_id &terrain_type = dat.terrain_type();
5035 if( terrain_type == "anthill" || terrain_type == "acid_anthill" ) {
5036 for( int i = 0; i < SEEX * 2; i++ ) {
5037 for( int j = 0; j < SEEY * 2; j++ ) {
5038 if( i < 8 || j < 8 || i > SEEX * 2 - 9 || j > SEEY * 2 - 9 ) {
5039 ter_set( point( i, j ), dat.groundcover() );
5040 } else if( ( i == 11 || i == 12 ) && ( j == 11 || j == 12 ) ) {
5041 ter_set( point( i, j ), t_slope_down );
5042 } else {
5043 ter_set( point( i, j ), t_dirtmound );
5044 }
5045 }
5046 }
5047 }
5048}
const oter_id & terrain_type() const
Definition: mapgendata.h:87
ter_id groundcover()
Definition: mapgendata.cpp:141
ter_id t_slope_down
Definition: mapdata.cpp:718
ter_id t_dirtmound
Definition: mapdata.cpp:625

References mapgendata::groundcover(), SEEX, SEEY, t_dirtmound, t_slope_down, ter_set(), and mapgendata::terrain_type().

Referenced by draw_map().

◆ draw_circle_furn()

void map::draw_circle_furn ( const furn_id type,
const point p,
int  rad 
)

Definition at line 8451 of file map.cpp.

8452{
8453 draw_circle( [this, type]( const point & q ) {
8454 this->furn_set( q, type );
8455 }, p, rad );
8456}
void draw_circle(std::function< void(const point &)>set, const rl_vec2d &p, double rad)

References draw_circle(), furn_set(), and type.

Referenced by circle_furn().

◆ draw_circle_ter() [1/2]

void map::draw_circle_ter ( const ter_id type,
const point p,
int  rad 
)

Definition at line 8444 of file map.cpp.

8445{
8446 draw_circle( [this, type]( const point & q ) {
8447 this->ter_set( q, type );
8448 }, p, rad );
8449}

References draw_circle(), ter_set(), and type.

◆ draw_circle_ter() [2/2]

void map::draw_circle_ter ( const ter_id type,
const rl_vec2d p,
double  rad 
)

Definition at line 8437 of file map.cpp.

8438{
8439 draw_circle( [this, type]( const point & q ) {
8440 this->ter_set( q, type );
8441 }, p, rad );
8442}

References draw_circle(), ter_set(), and type.

Referenced by circle().

◆ draw_connections()

void map::draw_connections ( mapgendata dat)
protected

Definition at line 5242 of file mapgen.cpp.

5243{
5244 const oter_id &terrain_type = dat.terrain_type();
5245 if( is_ot_match( "subway", terrain_type,
5246 ot_match_type::type ) ) { // FUUUUU it's IF ELIF ELIF ELIF's mini-me =[
5247 if( is_ot_match( "sewer", dat.north(), ot_match_type::type ) &&
5248 !connects_to( terrain_type, 0 ) ) {
5249 if( connects_to( dat.north(), 2 ) ) {
5250 for( int i = SEEX - 2; i < SEEX + 2; i++ ) {
5251 for( int j = 0; j < SEEY; j++ ) {
5252 ter_set( point( i, j ), t_sewage );
5253 }
5254 }
5255 } else {
5256 for( int j = 0; j < 3; j++ ) {
5257 ter_set( point( SEEX, j ), t_rock_floor );
5258 ter_set( point( SEEX - 1, j ), t_rock_floor );
5259 }
5260 ter_set( point( SEEX, 3 ), t_door_metal_c );
5261 ter_set( point( SEEX - 1, 3 ), t_door_metal_c );
5262 }
5263 }
5264 if( is_ot_match( "sewer", dat.east(), ot_match_type::type ) &&
5265 !connects_to( terrain_type, 1 ) ) {
5266 if( connects_to( dat.east(), 3 ) ) {
5267 for( int i = SEEX; i < SEEX * 2; i++ ) {
5268 for( int j = SEEY - 2; j < SEEY + 2; j++ ) {
5269 ter_set( point( i, j ), t_sewage );
5270 }
5271 }
5272 } else {
5273 for( int i = SEEX * 2 - 3; i < SEEX * 2; i++ ) {
5274 ter_set( point( i, SEEY ), t_rock_floor );
5275 ter_set( point( i, SEEY - 1 ), t_rock_floor );
5276 }
5277 ter_set( point( SEEX * 2 - 4, SEEY ), t_door_metal_c );
5278 ter_set( point( SEEX * 2 - 4, SEEY - 1 ), t_door_metal_c );
5279 }
5280 }
5281 if( is_ot_match( "sewer", dat.south(), ot_match_type::type ) &&
5282 !connects_to( terrain_type, 2 ) ) {
5283 if( connects_to( dat.south(), 0 ) ) {
5284 for( int i = SEEX - 2; i < SEEX + 2; i++ ) {
5285 for( int j = SEEY; j < SEEY * 2; j++ ) {
5286 ter_set( point( i, j ), t_sewage );
5287 }
5288 }
5289 } else {
5290 for( int j = SEEY * 2 - 3; j < SEEY * 2; j++ ) {
5291 ter_set( point( SEEX, j ), t_rock_floor );
5292 ter_set( point( SEEX - 1, j ), t_rock_floor );
5293 }
5294 ter_set( point( SEEX, SEEY * 2 - 4 ), t_door_metal_c );
5295 ter_set( point( SEEX - 1, SEEY * 2 - 4 ), t_door_metal_c );
5296 }
5297 }
5298 if( is_ot_match( "sewer", dat.west(), ot_match_type::type ) &&
5299 !connects_to( terrain_type, 3 ) ) {
5300 if( connects_to( dat.west(), 1 ) ) {
5301 for( int i = 0; i < SEEX; i++ ) {
5302 for( int j = SEEY - 2; j < SEEY + 2; j++ ) {
5303 ter_set( point( i, j ), t_sewage );
5304 }
5305 }
5306 } else {
5307 for( int i = 0; i < 3; i++ ) {
5308 ter_set( point( i, SEEY ), t_rock_floor );
5309 ter_set( point( i, SEEY - 1 ), t_rock_floor );
5310 }
5311 ter_set( point( 3, SEEY ), t_door_metal_c );
5312 ter_set( point( 3, SEEY - 1 ), t_door_metal_c );
5313 }
5314 }
5315 } else if( is_ot_match( "sewer", terrain_type, ot_match_type::type ) ) {
5316 if( dat.above() == "road_nesw_manhole" ) {
5317 ter_set( point( rng( SEEX - 2, SEEX + 1 ), rng( SEEY - 2, SEEY + 1 ) ), t_ladder_up );
5318 }
5319 if( is_ot_match( "subway", dat.north(), ot_match_type::type ) &&
5320 !connects_to( terrain_type, 0 ) ) {
5321 for( int j = 0; j < SEEY - 3; j++ ) {
5322 ter_set( point( SEEX, j ), t_rock_floor );
5323 ter_set( point( SEEX - 1, j ), t_rock_floor );
5324 }
5325 ter_set( point( SEEX, SEEY - 3 ), t_door_metal_c );
5326 ter_set( point( SEEX - 1, SEEY - 3 ), t_door_metal_c );
5327 }
5328 if( is_ot_match( "subway", dat.east(), ot_match_type::type ) &&
5329 !connects_to( terrain_type, 1 ) ) {
5330 for( int i = SEEX + 3; i < SEEX * 2; i++ ) {
5331 ter_set( point( i, SEEY ), t_rock_floor );
5332 ter_set( point( i, SEEY - 1 ), t_rock_floor );
5333 }
5334 ter_set( point( SEEX + 2, SEEY ), t_door_metal_c );
5335 ter_set( point( SEEX + 2, SEEY - 1 ), t_door_metal_c );
5336 }
5337 if( is_ot_match( "subway", dat.south(), ot_match_type::type ) &&
5338 !connects_to( terrain_type, 2 ) ) {
5339 for( int j = SEEY + 3; j < SEEY * 2; j++ ) {
5340 ter_set( point( SEEX, j ), t_rock_floor );
5341 ter_set( point( SEEX - 1, j ), t_rock_floor );
5342 }
5343 ter_set( point( SEEX, SEEY + 2 ), t_door_metal_c );
5344 ter_set( point( SEEX - 1, SEEY + 2 ), t_door_metal_c );
5345 }
5346 if( is_ot_match( "subway", dat.west(), ot_match_type::type ) &&
5347 !connects_to( terrain_type, 3 ) ) {
5348 for( int i = 0; i < SEEX - 3; i++ ) {
5349 ter_set( point( i, SEEY ), t_rock_floor );
5350 ter_set( point( i, SEEY - 1 ), t_rock_floor );
5351 }
5352 ter_set( point( SEEX - 3, SEEY ), t_door_metal_c );
5353 ter_set( point( SEEX - 3, SEEY - 1 ), t_door_metal_c );
5354 }
5355 } else if( is_ot_match( "ants", terrain_type, ot_match_type::type ) ) {
5356 if( dat.above() == "anthill" ) {
5357 if( const auto p = random_point( *this, [this]( const tripoint & n ) {
5358 return ter( n ) == t_rock_floor;
5359 } ) ) {
5360 ter_set( *p, t_slope_up );
5361 }
5362 }
5363 }
5364
5365 // finally, any terrain with SIDEWALKS should contribute sidewalks to neighboring diagonal roads
5366 if( terrain_type->has_flag( has_sidewalk ) ) {
5367 for( int dir = 4; dir < 8; dir++ ) { // NE SE SW NW
5368 bool n_roads_nesw[4] = {};
5369 int n_num_dirs = terrain_type_to_nesw_array( oter_id( dat.t_nesw[dir] ), n_roads_nesw );
5370 // only handle diagonal neighbors
5371 if( n_num_dirs == 2 &&
5372 n_roads_nesw[( ( dir - 4 ) + 3 ) % 4] &&
5373 n_roads_nesw[( ( dir - 4 ) + 2 ) % 4] ) {
5374 // make drawing simpler by rotating the map back and forth
5375 rotate( 4 - ( dir - 4 ) );
5376 // draw a small triangle of sidewalk in the northeast corner
5377 for( int y = 0; y < 4; y++ ) {
5378 for( int x = SEEX * 2 - 4; x < SEEX * 2; x++ ) {
5379 if( x - y > SEEX * 2 - 4 ) {
5380 // TODO: more discriminating conditions
5381 if( ter( point( x, y ) ) == t_grass || ter( point( x, y ) ) == t_dirt ||
5382 ter( point( x, y ) ) == t_shrub ) {
5383 ter_set( point( x, y ), t_sidewalk );
5384 }
5385 }
5386 }
5387 }
5388 rotate( ( dir - 4 ) );
5389 }
5390 }
5391 }
5392
5394}
void rotate(int turns, bool setpos_safe=false)
Rotates this map, and all of its contents, by the specified multiple of 90 degrees.
Definition: mapgen.cpp:5805
const oter_id & above() const
Definition: mapgendata.h:131
const oter_id & north() const
Definition: mapgendata.h:107
const oter_id & west() const
Definition: mapgendata.h:116
const oter_id & south() const
Definition: mapgendata.h:113
oter_id t_nesw[8]
Definition: mapgendata.h:45
const oter_id & east() const
Definition: mapgendata.h:110
cata::optional< tripoint > random_point(const map &m, const std::function< bool(const tripoint &)> &predicate)
Same as other random_point with a range enclosing all valid points of the map.
ter_id t_grass
Definition: mapdata.cpp:628
ter_id t_sewage
Definition: mapdata.cpp:694
ter_id t_slope_up
Definition: mapdata.cpp:719
ter_id t_ladder_up
Definition: mapdata.cpp:718
ter_id t_shrub
Definition: mapdata.cpp:683
ter_id t_sidewalk
Definition: mapdata.cpp:630
ter_id t_door_metal_c
Definition: mapdata.cpp:662
bool connects_to(const oter_id &there, int dir)
Definition: mapgen.cpp:5907
void resolve_regional_terrain_and_furniture(const mapgendata &dat)
int terrain_type_to_nesw_array(oter_id terrain_type, bool array[4])
@ has_sidewalk
Definition: omdata.h:90
bool is_ot_match(const std::string &name, const oter_id &oter, const ot_match_type match_type)
Determine if the provided name is a match with the provided overmap terrain based on the specified ma...
Definition: overmap.cpp:568
bool has_flag(oter_flags flag) const
Definition: omdata.h:258

References mapgendata::above(), connects_to(), mapgendata::east(), oter_t::has_flag(), has_sidewalk, is_ot_match(), mapgendata::north(), oter_id, random_point(), resolve_regional_terrain_and_furniture(), rng(), rotate(), SEEX, SEEY, mapgendata::south(), t_dirt, t_door_metal_c, t_grass, t_ladder_up, mapgendata::t_nesw, t_rock_floor, t_sewage, t_shrub, t_sidewalk, t_slope_up, ter(), ter_set(), mapgendata::terrain_type(), terrain_type_to_nesw_array(), type, and mapgendata::west().

Referenced by draw_map().

◆ draw_fill_background() [1/3]

void map::draw_fill_background ( const ter_id type)

Definition at line 8366 of file map.cpp.

8367{
8368 // Need to explicitly set caches dirty - set_ter would do it before
8373
8374 // Fill each submap rather than each tile
8375 for( int gridx = 0; gridx < my_MAPSIZE; gridx++ ) {
8376 for( int gridy = 0; gridy < my_MAPSIZE; gridy++ ) {
8377 auto sm = get_submap_at_grid( {gridx, gridy} );
8378 sm->is_uniform = true;
8379 sm->set_all_ter( type );
8380 }
8381 }
8382}
void set_outside_cache_dirty(const int zlev)
Definition: map.h:442

References abs_sub, get_submap_at_grid(), my_MAPSIZE, set_outside_cache_dirty(), set_pathfinding_cache_dirty(), set_seen_cache_dirty(), set_transparency_cache_dirty(), coords::sm, type, and tripoint::z.

Referenced by fill_background(), mapgendata::fill_groundcover(), mapgen_function_json::generate(), and mapgen_forest().

◆ draw_fill_background() [2/3]

void map::draw_fill_background ( const weighted_int_list< ter_id > &  f)

Definition at line 8388 of file map.cpp.

8389{
8391}
void draw_square_ter(const ter_id &type, const point &p1, const point &p2)
Definition: map.cpp:8393

References draw_square_ter(), my_MAPSIZE, point_zero, SEEX, and SEEY.

◆ draw_fill_background() [3/3]

void map::draw_fill_background ( ter_id(*)()  f)

Definition at line 8384 of file map.cpp.

8385{
8387}

References draw_square_ter(), my_MAPSIZE, point_zero, SEEX, and SEEY.

◆ draw_from_above()

void map::draw_from_above ( const catacurses::window w,
const tripoint p,
const maptile tile,
const drawsq_params params 
) const
private

Draws the tile as seen from above.

Definition at line 6068 of file map.cpp.

6070{
6071 static const int AUTO_WALL_PLACEHOLDER = 2; // this should never appear as a real symbol!
6072
6073 nc_color tercol = c_dark_gray;
6074 int sym = ' ';
6075
6076 const ter_t &curr_ter = curr_tile.get_ter_t();
6077 const furn_t &curr_furn = curr_tile.get_furn_t();
6078 int part_below;
6079 const vehicle *veh;
6080 if( curr_furn.has_flag( TFLAG_SEEN_FROM_ABOVE ) ) {
6081 sym = curr_furn.symbol();
6082 tercol = curr_furn.color();
6083 } else if( curr_furn.movecost < 0 ) {
6084 sym = '.';
6085 tercol = curr_furn.color();
6086 } else if( ( veh = veh_at_internal( p, part_below ) ) != nullptr ) {
6087 const int roof = veh->roof_at_part( part_below );
6088 const int displayed_part = roof >= 0 ? roof : part_below;
6089 sym = special_symbol( veh->face.dir_symbol( veh->part_sym( displayed_part, true ) ) );
6090 tercol = ( roof >= 0 ||
6091 vpart_position( const_cast<vehicle &>( *veh ),
6092 part_below ).obstacle_at_part() ) ? c_light_gray : c_light_gray_cyan;
6093 } else if( curr_ter.has_flag( TFLAG_SEEN_FROM_ABOVE ) ) {
6094 if( curr_ter.has_flag( TFLAG_AUTO_WALL_SYMBOL ) ) {
6095 sym = AUTO_WALL_PLACEHOLDER;
6096 } else if( curr_ter.has_flag( TFLAG_RAMP ) ) {
6097 sym = '>';
6098 } else {
6099 sym = curr_ter.symbol();
6100 }
6101 tercol = curr_ter.color();
6102 } else if( curr_ter.movecost == 0 ) {
6103 sym = '.';
6104 tercol = curr_ter.color();
6105 } else if( !curr_ter.has_flag( TFLAG_NO_FLOOR ) ) {
6106 sym = '.';
6107 if( curr_ter.color() != c_cyan ) {
6108 // Need a special case here, it doesn't cyanize well
6109 tercol = cyan_background( curr_ter.color() );
6110 } else {
6111 tercol = c_black_cyan;
6112 }
6113 } else {
6114 sym = curr_ter.symbol();
6115 tercol = curr_ter.color();
6116 }
6117
6118 if( sym == AUTO_WALL_PLACEHOLDER ) {
6119 sym = determine_wall_corner( p );
6120 }
6121
6122 const auto u_vision = g->u.get_vision_modes();
6123 if( u_vision[BOOMERED] ) {
6124 tercol = c_magenta;
6125 } else if( u_vision[NV_GOGGLES] ) {
6126 tercol = params.bright_light() ? c_white : c_light_green;
6127 } else if( params.low_light() ) {
6128 tercol = c_dark_gray;
6129 } else if( u_vision[DARKNESS] ) {
6130 tercol = c_dark_gray;
6131 }
6132
6133 if( params.highlight() ) {
6134 tercol = invert_color( tercol );
6135 }
6136
6137 if( params.output() ) {
6138 wputch( w, tercol, sym );
6139 }
6140}
@ DARKNESS
Definition: character.h:93
@ NV_GOGGLES
Definition: character.h:89
@ BOOMERED
Definition: character.h:92
int determine_wall_corner(const tripoint &p) const
Definition: map.cpp:7856
vehicle * veh_at_internal(const tripoint &p, int &part_num)
Definition: map.cpp:1044
int dir_symbol(int sym) const
Definition: tileray.cpp:113
char part_sym(int p, bool exact=false) const
int roof_at_part(int p) const
Definition: vehicle.cpp:3012
tileray face
Definition: vehicle.h:1948
cata::optional< vpart_reference > obstacle_at_part() const
Returns the obstacle that exists at this point of the vehicle (if any).
Definition: vehicle.cpp:2438
nc_color invert_color(const nc_color &c)
Definition: color.cpp:503
nc_color cyan_background(const nc_color &c)
Definition: color.cpp:545
#define c_white
Definition: color.h:18
#define c_light_green
Definition: color.h:28
#define c_dark_gray
Definition: color.h:20
#define c_black_cyan
Definition: color.h:154
#define c_cyan
Definition: color.h:24
#define c_light_gray_cyan
Definition: color.h:156
@ TFLAG_AUTO_WALL_SYMBOL
Definition: mapdata.h:305
@ TFLAG_SEEN_FROM_ABOVE
Definition: mapdata.h:311
int special_symbol(int sym)
Definition: output.cpp:1095
constexpr drawsq_params & highlight(bool v)
Highlight the tile.
Definition: map.h:198
nc_color color() const
Definition: mapdata.cpp:555

References BOOMERED, drawsq_params::bright_light(), c_black_cyan, c_cyan, c_dark_gray, c_light_gray, c_light_gray_cyan, c_light_green, c_magenta, c_white, map_data_common_t::color(), cyan_background(), DARKNESS, determine_wall_corner(), tileray::dir_symbol(), vehicle::face, g, maptile::get_furn_t(), maptile::get_ter_t(), map_data_common_t::has_flag(), drawsq_params::highlight(), invert_color(), drawsq_params::low_light(), map_data_common_t::movecost, NV_GOGGLES, vpart_position::obstacle_at_part(), drawsq_params::output(), vehicle::part_sym(), vehicle::roof_at_part(), special_symbol(), map_data_common_t::symbol(), TFLAG_AUTO_WALL_SYMBOL, TFLAG_NO_FLOOR, TFLAG_RAMP, TFLAG_SEEN_FROM_ABOVE, veh_at_internal(), and wputch().

Referenced by draw(), and drawsq().

◆ draw_lab()

void map::draw_lab ( mapgendata dat)
protected

Definition at line 3522 of file mapgen.cpp.

3523{
3524 const oter_id &terrain_type = dat.terrain_type();
3525 // To distinguish between types of labs
3526 bool ice_lab = true;
3527 bool central_lab = false;
3528 bool tower_lab = false;
3529
3530 point p2;
3531
3532 int lw = 0;
3533 int rw = 0;
3534 int tw = 0;
3535 int bw = 0;
3536
3537 if( terrain_type == "lab" || terrain_type == "lab_stairs" || terrain_type == "lab_core" ||
3538 terrain_type == "ants_lab" || terrain_type == "ants_lab_stairs" ||
3539 terrain_type == "ice_lab" || terrain_type == "ice_lab_stairs" ||
3540 terrain_type == "ice_lab_core" ||
3541 terrain_type == "central_lab" || terrain_type == "central_lab_stairs" ||
3542 terrain_type == "central_lab_core" ||
3543 terrain_type == "tower_lab" || terrain_type == "tower_lab_stairs" ) {
3544
3545 ice_lab = is_ot_match( "ice_lab", terrain_type, ot_match_type::prefix );
3546 central_lab = is_ot_match( "central_lab", terrain_type, ot_match_type::prefix );
3547 tower_lab = is_ot_match( "tower_lab", terrain_type, ot_match_type::prefix );
3548
3549 if( ice_lab ) {
3550 int temperature = -20 + 30 * ( dat.zlevel() );
3552 set_temperature( p2 + point( SEEX, 0 ), temperature );
3553 set_temperature( p2 + point( 0, SEEY ), temperature );
3555 }
3556
3557 // Check for adjacent sewers; used below
3558 tw = 0;
3559 rw = 0;
3560 bw = 0;
3561 lw = 0;
3562 if( is_ot_match( "sewer", dat.north(), ot_match_type::type ) && connects_to( dat.north(), 2 ) ) {
3563 tw = SOUTH_EDGE + 1;
3564 }
3565 if( is_ot_match( "sewer", dat.east(), ot_match_type::type ) && connects_to( dat.east(), 3 ) ) {
3566 rw = EAST_EDGE + 1;
3567 }
3568 if( is_ot_match( "sewer", dat.south(), ot_match_type::type ) && connects_to( dat.south(), 0 ) ) {
3569 bw = SOUTH_EDGE + 1;
3570 }
3571 if( is_ot_match( "sewer", dat.west(), ot_match_type::type ) && connects_to( dat.west(), 1 ) ) {
3572 lw = EAST_EDGE + 1;
3573 }
3574 if( dat.zlevel() == 0 ) { // We're on ground level
3575 for( int i = 0; i < SEEX * 2; i++ ) {
3576 for( int j = 0; j < SEEY * 2; j++ ) {
3577 if( i <= 1 || i >= SEEX * 2 - 2 ||
3578 ( j > 1 && j < SEEY * 2 - 2 && ( i == SEEX - 2 || i == SEEX + 1 ) ) ) {
3579 ter_set( point( i, j ), t_concrete_wall );
3580 } else if( j <= 1 || j >= SEEY * 2 - 2 ) {
3581 ter_set( point( i, j ), t_concrete_wall );
3582 } else {
3583 ter_set( point( i, j ), t_floor );
3584 }
3585 }
3586 }
3587 ter_set( point( SEEX - 1, 0 ), t_door_metal_locked );
3588 ter_set( point( SEEX - 1, 1 ), t_floor );
3590 ter_set( point( SEEX, 1 ), t_floor );
3591 ter_set( point( SEEX - 2 + rng( 0, 1 ) * 3, 0 ), t_card_science );
3592 ter_set( point( SEEX - 2, SEEY ), t_door_metal_c );
3593 ter_set( point( SEEX + 1, SEEY ), t_door_metal_c );
3594 ter_set( point( SEEX - 2, SEEY - 1 ), t_door_metal_c );
3595 ter_set( point( SEEX + 1, SEEY - 1 ), t_door_metal_c );
3596 ter_set( point( SEEX - 1, SEEY * 2 - 3 ), t_stairs_down );
3597 ter_set( point( SEEX, SEEY * 2 - 3 ), t_stairs_down );
3598 science_room( this, point( 2, 2 ), point( SEEX - 3, SEEY * 2 - 3 ), dat.zlevel(), 1 );
3599 science_room( this, point( SEEX + 2, 2 ), point( SEEX * 2 - 3, SEEY * 2 - 3 ), dat.zlevel(), 3 );
3600
3601 place_spawns( GROUP_TURRET, 1, point( SEEX, 5 ), point( SEEX, 5 ), 1, true );
3602
3603 if( is_ot_match( "road", dat.east(), ot_match_type::type ) ) {
3604 rotate( 1 );
3605 } else if( is_ot_match( "road", dat.south(), ot_match_type::type ) ) {
3606 rotate( 2 );
3607 } else if( is_ot_match( "road", dat.west(), ot_match_type::type ) ) {
3608 rotate( 3 );
3609 }
3610 } else if( tw != 0 || rw != 0 || lw != 0 || bw != 0 ) { // Sewers!
3611 for( int i = 0; i < SEEX * 2; i++ ) {
3612 for( int j = 0; j < SEEY * 2; j++ ) {
3613 ter_set( point( i, j ), t_thconc_floor );
3614 if( ( ( i < lw || i > EAST_EDGE - rw ) && j > SEEY - 3 && j < SEEY + 2 ) ||
3615 ( ( j < tw || j > SOUTH_EDGE - bw ) && i > SEEX - 3 && i < SEEX + 2 ) ) {
3616 ter_set( point( i, j ), t_sewage );
3617 }
3618 if( ( i == 0 && is_ot_match( "lab", dat.east(), ot_match_type::contains ) ) || i == EAST_EDGE ) {
3619 if( ter( point( i, j ) ) == t_sewage ) {
3620 ter_set( point( i, j ), t_bars );
3621 } else if( j == SEEY - 1 || j == SEEY ) {
3622 ter_set( point( i, j ), t_door_metal_c );
3623 } else {
3624 ter_set( point( i, j ), t_concrete_wall );
3625 }
3626 } else if( ( j == 0 && is_ot_match( "lab", dat.north(), ot_match_type::contains ) ) ||
3627 j == SOUTH_EDGE ) {
3628 if( ter( point( i, j ) ) == t_sewage ) {
3629 ter_set( point( i, j ), t_bars );
3630 } else if( i == SEEX - 1 || i == SEEX ) {
3631 ter_set( point( i, j ), t_door_metal_c );
3632 } else {
3633 ter_set( point( i, j ), t_concrete_wall );
3634 }
3635 }
3636 }
3637 }
3638 } else { // We're below ground, and no sewers
3639 // Set up the boundaries of walls (connect to adjacent lab squares)
3640 tw = is_ot_match( "lab", dat.north(), ot_match_type::contains ) ? 0 : 2;
3641 rw = is_ot_match( "lab", dat.east(), ot_match_type::contains ) ? 1 : 2;
3642 bw = is_ot_match( "lab", dat.south(), ot_match_type::contains ) ? 1 : 2;
3643 lw = is_ot_match( "lab", dat.west(), ot_match_type::contains ) ? 0 : 2;
3644
3645 int boarders = 0;
3646 if( tw == 0 ) {
3647 boarders++;
3648 }
3649 if( rw == 1 ) {
3650 boarders++;
3651 }
3652 if( bw == 1 ) {
3653 boarders++;
3654 }
3655 if( lw == 0 ) {
3656 boarders++;
3657 }
3658
3659 const auto maybe_insert_stairs = [this]( const oter_id & terrain, const ter_id & t_stair_type ) {
3660 if( is_ot_match( "stairs", terrain, ot_match_type::contains ) ) {
3661 const auto predicate = [this]( const tripoint & p ) {
3662 return ter( p ) == t_thconc_floor && furn( p ) == f_null && tr_at( p ).is_null();
3663 };
3664 const auto range = points_in_rectangle( { 0, 0, abs_sub.z }, { SEEX * 2 - 2, SEEY * 2 - 2, abs_sub.z } );
3665
3666 if( const auto p = random_point( range, predicate ) ) {
3667 ter_set( *p, t_stair_type );
3668 }
3669 }
3670 };
3671
3672 //A lab area with only one entrance
3673 if( boarders == 1 ) {
3674 // If you remove the usage of "lab_1side" here, remove it from mapgen_factory::get_usages above as well.
3675 if( oter_mapgen.generate( dat, "lab_1side" ) ) {
3676 if( tw == 2 ) {
3677 rotate( 2 );
3678 }
3679 if( rw == 2 ) {
3680 rotate( 1 );
3681 }
3682 if( lw == 2 ) {
3683 rotate( 3 );
3684 }
3685 } else {
3686 debugmsg( "Error: Tried to generate 1-sided lab but no lab_1side json exists." );
3687 }
3688 maybe_insert_stairs( dat.above(), t_stairs_up );
3689 maybe_insert_stairs( terrain_type, t_stairs_down );
3690 } else {
3691 const int hardcoded_4side_map_weight = 1500; // weight of all hardcoded maps.
3692 // If you remove the usage of "lab_4side" here, remove it from mapgen_factory::get_usages above as well.
3693 if( oter_mapgen.generate( dat, "lab_4side", hardcoded_4side_map_weight ) ) {
3694 // If the map template hasn't handled borders, handle them in code.
3695 // Rotated maps cannot handle borders and have to be caught in code.
3696 // We determine if a border isn't handled by checking the east-facing
3697 // border space where the door normally is -- it should be a wall or door.
3698 tripoint east_border( 23, 11, abs_sub.z );
3699 if( !has_flag_ter( "WALL", east_border ) &&
3700 !has_flag_ter( "DOOR", east_border ) ) {
3701 // TODO: create a ter_reset function that does ter_set,
3702 // furn_set, and i_clear?
3703 ter_id lw_type = tower_lab ? t_reinforced_glass : t_concrete_wall;
3704 ter_id tw_type = tower_lab ? t_reinforced_glass : t_concrete_wall;
3705 ter_id rw_type = tower_lab && rw == 2 ? t_reinforced_glass :
3707 ter_id bw_type = tower_lab && bw == 2 ? t_reinforced_glass :
3709 for( int i = 0; i < SEEX * 2; i++ ) {
3710 ter_set( point( 23, i ), rw_type );
3711 furn_set( point( 23, i ), f_null );
3712 i_clear( tripoint( 23, i, get_abs_sub().z ) );
3713
3714 ter_set( point( i, 23 ), bw_type );
3715 furn_set( point( i, 23 ), f_null );
3716 i_clear( tripoint( i, 23, get_abs_sub().z ) );
3717
3718 if( lw == 2 ) {
3719 ter_set( point( 0, i ), lw_type );
3720 furn_set( point( 0, i ), f_null );
3721 i_clear( tripoint( 0, i, get_abs_sub().z ) );
3722 }
3723 if( tw == 2 ) {
3724 ter_set( point( i, 0 ), tw_type );
3725 furn_set( point( i, 0 ), f_null );
3726 i_clear( tripoint( i, 0, get_abs_sub().z ) );
3727 }
3728 }
3729 if( rw != 2 ) {
3730 ter_set( point( 23, 11 ), t_door_metal_c );
3731 ter_set( point( 23, 12 ), t_door_metal_c );
3732 }
3733 if( bw != 2 ) {
3734 ter_set( point( 11, 23 ), t_door_metal_c );
3735 ter_set( point( 12, 23 ), t_door_metal_c );
3736 }
3737 }
3738
3739 maybe_insert_stairs( dat.above(), t_stairs_up );
3740 maybe_insert_stairs( terrain_type, t_stairs_down );
3741 } else { // then no json maps for lab_4side were found
3742 switch( rng( 1, 3 ) ) {
3743 case 1:
3744 // Cross shaped
3745 for( int i = 0; i < SEEX * 2; i++ ) {
3746 for( int j = 0; j < SEEY * 2; j++ ) {
3747 if( ( i < lw || i > EAST_EDGE - rw ) ||
3748 ( ( j < SEEY - 1 || j > SEEY ) &&
3749 ( i == SEEX - 2 || i == SEEX + 1 ) ) ) {
3750 ter_set( point( i, j ), t_concrete_wall );
3751 } else if( ( j < tw || j > SOUTH_EDGE - bw ) ||
3752 ( ( i < SEEX - 1 || i > SEEX ) &&
3753 ( j == SEEY - 2 || j == SEEY + 1 ) ) ) {
3754 ter_set( point( i, j ), t_concrete_wall );
3755 } else {
3756 ter_set( point( i, j ), t_thconc_floor );
3757 }
3758 }
3759 }
3760 if( is_ot_match( "stairs", dat.above(), ot_match_type::contains ) ) {
3761 ter_set( point( rng( SEEX - 1, SEEX ), rng( SEEY - 1, SEEY ) ),
3762 t_stairs_up );
3763 }
3764 // Top left
3765 if( one_in( 2 ) ) {
3766 ter_set( point( SEEX - 2, int( SEEY / 2 ) ), t_door_glass_frosted_c );
3767 science_room( this, point( lw, tw ), point( SEEX - 3, SEEY - 3 ), dat.zlevel(), 1 );
3768 } else {
3770 science_room( this, point( lw, tw ), point( SEEX - 3, SEEY - 3 ), dat.zlevel(), 2 );
3771 }
3772 // Top right
3773 if( one_in( 2 ) ) {
3774 ter_set( point( SEEX + 1, int( SEEY / 2 ) ), t_door_glass_frosted_c );
3775 science_room( this, point( SEEX + 2, tw ), point( EAST_EDGE - rw, SEEY - 3 ),
3776 dat.zlevel(), 3 );
3777 } else {
3778 ter_set( point( SEEX + int( SEEX / 2 ), SEEY - 2 ), t_door_glass_frosted_c );
3779 science_room( this, point( SEEX + 2, tw ), point( EAST_EDGE - rw, SEEY - 3 ),
3780 dat.zlevel(), 2 );
3781 }
3782 // Bottom left
3783 if( one_in( 2 ) ) {
3785 science_room( this, point( lw, SEEY + 2 ), point( SEEX - 3, SOUTH_EDGE - bw ),
3786 dat.zlevel(), 0 );
3787 } else {
3788 ter_set( point( SEEX - 2, SEEY + int( SEEY / 2 ) ), t_door_glass_frosted_c );
3789 science_room( this, point( lw, SEEY + 2 ), point( SEEX - 3, SOUTH_EDGE - bw ),
3790 dat.zlevel(), 1 );
3791 }
3792 // Bottom right
3793 if( one_in( 2 ) ) {
3794 ter_set( point( SEEX + int( SEEX / 2 ), SEEY + 1 ), t_door_glass_frosted_c );
3795 science_room( this, point( SEEX + 2, SEEY + 2 ), point( EAST_EDGE - rw, SOUTH_EDGE - bw ),
3796 dat.zlevel(), 0 );
3797 } else {
3798 ter_set( point( SEEX + 1, SEEY + int( SEEY / 2 ) ), t_door_glass_frosted_c );
3799 science_room( this, point( SEEX + 2, SEEY + 2 ), point( EAST_EDGE - rw, SOUTH_EDGE - bw ),
3800 dat.zlevel(), 3 );
3801 }
3802 if( rw == 1 ) {
3805 }
3806 if( bw == 1 ) {
3809 }
3810 if( is_ot_match( "stairs", terrain_type, ot_match_type::contains ) ) { // Stairs going down
3811 std::vector<point> stair_points;
3812 if( tw != 0 ) {
3813 stair_points.push_back( point( SEEX - 1, 2 ) );
3814 stair_points.push_back( point( SEEX - 1, 2 ) );
3815 stair_points.push_back( point( SEEX, 2 ) );
3816 stair_points.push_back( point( SEEX, 2 ) );
3817 }
3818 if( rw != 1 ) {
3819 stair_points.push_back( point( SEEX * 2 - 3, SEEY - 1 ) );
3820 stair_points.push_back( point( SEEX * 2 - 3, SEEY - 1 ) );
3821 stair_points.push_back( point( SEEX * 2 - 3, SEEY ) );
3822 stair_points.push_back( point( SEEX * 2 - 3, SEEY ) );
3823 }
3824 if( bw != 1 ) {
3825 stair_points.push_back( point( SEEX - 1, SEEY * 2 - 3 ) );
3826 stair_points.push_back( point( SEEX - 1, SEEY * 2 - 3 ) );
3827 stair_points.push_back( point( SEEX, SEEY * 2 - 3 ) );
3828 stair_points.push_back( point( SEEX, SEEY * 2 - 3 ) );
3829 }
3830 if( lw != 0 ) {
3831 stair_points.push_back( point( 2, SEEY - 1 ) );
3832 stair_points.push_back( point( 2, SEEY - 1 ) );
3833 stair_points.push_back( point( 2, SEEY ) );
3834 stair_points.push_back( point( 2, SEEY ) );
3835 }
3836 stair_points.push_back( point( int( SEEX / 2 ), SEEY ) );
3837 stair_points.push_back( point( int( SEEX / 2 ), SEEY - 1 ) );
3838 stair_points.push_back( point( int( SEEX / 2 ) + SEEX, SEEY ) );
3839 stair_points.push_back( point( int( SEEX / 2 ) + SEEX, SEEY - 1 ) );
3840 stair_points.push_back( point( SEEX, int( SEEY / 2 ) ) );
3841 stair_points.push_back( point( SEEX + 2, int( SEEY / 2 ) ) );
3842 stair_points.push_back( point( SEEX, int( SEEY / 2 ) + SEEY ) );
3843 stair_points.push_back( point( SEEX + 2, int( SEEY / 2 ) + SEEY ) );
3844 const point p = random_entry( stair_points );
3845 ter_set( p, t_stairs_down );
3846 }
3847
3848 break;
3849
3850 case 2:
3851 // tic-tac-toe # layout
3852 for( int i = 0; i < SEEX * 2; i++ ) {
3853 for( int j = 0; j < SEEY * 2; j++ ) {
3854 if( i < lw || i > EAST_EDGE - rw || i == SEEX - 4 ||
3855 i == SEEX + 3 ) {
3856 ter_set( point( i, j ), t_concrete_wall );
3857 } else if( j < tw || j > SOUTH_EDGE - bw || j == SEEY - 4 ||
3858 j == SEEY + 3 ) {
3859 ter_set( point( i, j ), t_concrete_wall );
3860 } else {
3861 ter_set( point( i, j ), t_thconc_floor );
3862 }
3863 }
3864 }
3865 if( is_ot_match( "stairs", dat.above(), ot_match_type::contains ) ) {
3866 ter_set( point( SEEX - 1, SEEY - 1 ), t_stairs_up );
3867 ter_set( point( SEEX, SEEY - 1 ), t_stairs_up );
3868 ter_set( point( SEEX - 1, SEEY ), t_stairs_up );
3870 }
3871 ter_set( point( SEEX - rng( 0, 1 ), SEEY - 4 ), t_door_glass_frosted_c );
3872 ter_set( point( SEEX - rng( 0, 1 ), SEEY + 3 ), t_door_glass_frosted_c );
3873 ter_set( point( SEEX - 4, SEEY + rng( 0, 1 ) ), t_door_glass_frosted_c );
3874 ter_set( point( SEEX + 3, SEEY + rng( 0, 1 ) ), t_door_glass_frosted_c );
3875 ter_set( point( SEEX - 4, int( SEEY / 2 ) ), t_door_glass_frosted_c );
3876 ter_set( point( SEEX + 3, int( SEEY / 2 ) ), t_door_glass_frosted_c );
3879 ter_set( point( SEEX + int( SEEX / 2 ), SEEY - 4 ), t_door_glass_frosted_c );
3880 ter_set( point( SEEX + int( SEEX / 2 ), SEEY + 3 ), t_door_glass_frosted_c );
3881 ter_set( point( SEEX - 4, SEEY + int( SEEY / 2 ) ), t_door_glass_frosted_c );
3882 ter_set( point( SEEX + 3, SEEY + int( SEEY / 2 ) ), t_door_glass_frosted_c );
3883 science_room( this, point( lw, tw ), point( SEEX - 5, SEEY - 5 ), dat.zlevel(),
3884 rng( 1, 2 ) );
3885 science_room( this, point( SEEX - 3, tw ), point( SEEX + 2, SEEY - 5 ), dat.zlevel(), 2 );
3886 science_room( this, point( SEEX + 4, tw ), point( EAST_EDGE - rw, SEEY - 5 ),
3887 dat.zlevel(), rng( 2, 3 ) );
3888 science_room( this, point( lw, SEEY - 3 ), point( SEEX - 5, SEEY + 2 ), dat.zlevel(), 1 );
3889 science_room( this, point( SEEX + 4, SEEY - 3 ), point( EAST_EDGE - rw, SEEY + 2 ),
3890 dat.zlevel(), 3 );
3891 science_room( this, point( lw, SEEY + 4 ), point( SEEX - 5, SOUTH_EDGE - bw ),
3892 dat.zlevel(), rng( 0, 1 ) );
3893 science_room( this, point( SEEX - 3, SEEY + 4 ), point( SEEX + 2, SOUTH_EDGE - bw ),
3894 dat.zlevel(), 0 );
3895 science_room( this, point( SEEX + 4, SEEX + 4 ), point( EAST_EDGE - rw, SOUTH_EDGE - bw ),
3896 dat.zlevel(), 3 * rng( 0, 1 ) );
3897 if( rw == 1 ) {
3900 }
3901 if( bw == 1 ) {
3904 }
3905 if( is_ot_match( "stairs", terrain_type, ot_match_type::contains ) ) {
3906 ter_set( point( SEEX - 3 + 5 * rng( 0, 1 ), SEEY - 3 + 5 * rng( 0, 1 ) ),
3907 t_stairs_down );
3908 }
3909 break;
3910
3911 case 3:
3912 // Big room
3913 for( int i = 0; i < SEEX * 2; i++ ) {
3914 for( int j = 0; j < SEEY * 2; j++ ) {
3915 if( i < lw || i >= EAST_EDGE - rw ) {
3916 ter_set( point( i, j ), t_concrete_wall );
3917 } else if( j < tw || j >= SOUTH_EDGE - bw ) {
3918 ter_set( point( i, j ), t_concrete_wall );
3919 } else {
3920 ter_set( point( i, j ), t_thconc_floor );
3921 }
3922 }
3923 }
3924 science_room( this, point( lw, tw ), point( EAST_EDGE - rw, SOUTH_EDGE - bw ),
3925 dat.zlevel(), rng( 0, 3 ) );
3926
3927 if( rw == 1 ) {
3930 }
3931 if( bw == 1 ) {
3934 }
3935 maybe_insert_stairs( dat.above(), t_stairs_up );
3936 maybe_insert_stairs( terrain_type, t_stairs_down );
3937 break;
3938 }
3939 } // endif use_hardcoded_4side_map
3940 } // end 1 vs 4 sides
3941 } // end aboveground vs belowground
3942
3943 // Ants will totally wreck up the place
3944 if( is_ot_match( "ants", terrain_type, ot_match_type::contains ) ) {
3945 for( int i = 0; i < SEEX * 2; i++ ) {
3946 for( int j = 0; j < SEEY * 2; j++ ) {
3947 // Carve out a diamond area that covers 2 spaces on each edge.
3948 if( i + j > 10 && i + j < 36 && std::abs( i - j ) < 13 ) {
3949 // Doors and walls get sometimes destroyed:
3950 // 100% at the edge, usually in a central cross, occasionally elsewhere.
3951 if( ( has_flag_ter( "DOOR", point( i, j ) ) || has_flag_ter( "WALL", point( i, j ) ) ) ) {
3952 if( ( i == 0 || j == 0 || i == 23 || j == 23 ) ||
3953 ( !one_in( 3 ) && ( i == 11 || i == 12 || j == 11 || j == 12 ) ) ||
3954 one_in( 4 ) ) {
3955 // bash and usually remove the rubble.
3956 make_rubble( { i, j, abs_sub.z } );
3957 ter_set( point( i, j ), t_rock_floor );
3958 if( !one_in( 3 ) ) {
3959 furn_set( point( i, j ), f_null );
3960 }
3961 }
3962 // and then randomly destroy 5% of the remaining nonstairs.
3963 } else if( one_in( 20 ) &&
3964 !has_flag_ter( "GOES_DOWN", p2 ) &&
3965 !has_flag_ter( "GOES_UP", p2 ) ) {
3966 destroy( { i, j, abs_sub.z } );
3967 // bashed squares can create dirt & floors, but we want rock floors.
3968 if( t_dirt == ter( point( i, j ) ) || t_floor == ter( point( i, j ) ) ) {
3969 ter_set( point( i, j ), t_rock_floor );
3970 }
3971 }
3972 }
3973 }
3974 }
3975 }
3976
3977 // Slimes pretty much wreck up the place, too, but only underground
3978 tw = ( dat.north() == "slimepit" ? SEEY : 0 );
3979 rw = ( dat.east() == "slimepit" ? SEEX + 1 : 0 );
3980 bw = ( dat.south() == "slimepit" ? SEEY + 1 : 0 );
3981 lw = ( dat.west() == "slimepit" ? SEEX : 0 );
3982 if( tw != 0 || rw != 0 || bw != 0 || lw != 0 ) {
3983 for( int i = 0; i < SEEX * 2; i++ ) {
3984 for( int j = 0; j < SEEY * 2; j++ ) {
3985 if( ( ( j <= tw || i >= rw ) && i >= j && ( EAST_EDGE - i ) <= j ) ||
3986 ( ( j >= bw || i <= lw ) && i <= j && ( SOUTH_EDGE - j ) <= i ) ) {
3987 if( one_in( 5 ) ) {
3988 make_rubble( tripoint( i, j, abs_sub.z ), f_rubble_rock, true,
3989 t_slime );
3990 } else if( !one_in( 5 ) ) {
3991 ter_set( point( i, j ), t_slime );
3992 }
3993 }
3994 }
3995 }
3996 }
3997
3998 int light_odds = 0;
3999 // central labs are always fully lit, other labs have half chance of some lights.
4000 if( central_lab ) {
4001 light_odds = 1;
4002 } else if( one_in( 2 ) ) {
4003 // Create a spread of densities, from all possible lights on, to 1/3, ...
4004 // to ~1 per segment.
4005 light_odds = std::pow( rng( 1, 12 ), 1.6 );
4006 }
4007 if( light_odds > 0 ) {
4008 for( int i = 0; i < SEEX * 2; i++ ) {
4009 for( int j = 0; j < SEEY * 2; j++ ) {
4010 if( !( ( i * j ) % 2 || ( i + j ) % 4 ) && one_in( light_odds ) ) {
4011 if( t_thconc_floor == ter( point( i, j ) ) || t_strconc_floor == ter( point( i, j ) ) ) {
4013 }
4014 }
4015 }
4016 }
4017 }
4018
4019 if( tower_lab ) {
4021 }
4022
4023 // Lab special effects.
4024 if( one_in( 10 ) ) {
4025 switch( rng( 1, 7 ) ) {
4026 // full flooding/sewage
4027 case 1: {
4028 if( is_ot_match( "stairs", terrain_type, ot_match_type::contains ) ||
4029 is_ot_match( "ice", terrain_type, ot_match_type::contains ) ) {
4030 // don't flood if stairs because the floor below will not be flooded.
4031 // don't flood if ice lab because there's no mechanic for freezing
4032 // liquid floors.
4033 break;
4034 }
4035 auto fluid_type = one_in( 3 ) ? t_sewage : t_water_sh;
4036 for( int i = 0; i < EAST_EDGE; i++ ) {
4037 for( int j = 0; j < SOUTH_EDGE; j++ ) {
4038 // We spare some terrain to make it look better visually.
4039 if( !one_in( 10 ) && ( t_thconc_floor == ter( point( i, j ) ) ||
4040 t_strconc_floor == ter( point( i, j ) ) ||
4041 t_thconc_floor_olight == ter( point( i, j ) ) ) ) {
4042 ter_set( point( i, j ), fluid_type );
4043 } else if( has_flag_ter( "DOOR", point( i, j ) ) && !one_in( 3 ) ) {
4044 // We want the actual debris, but not the rubble marker or dirt.
4045 make_rubble( { i, j, abs_sub.z } );
4046 ter_set( point( i, j ), fluid_type );
4047 furn_set( point( i, j ), f_null );
4048 }
4049 }
4050 }
4051 break;
4052 }
4053 // minor flooding/sewage
4054 case 2: {
4055 if( is_ot_match( "stairs", terrain_type, ot_match_type::contains ) ||
4056 is_ot_match( "ice", terrain_type, ot_match_type::contains ) ) {
4057 // don't flood if stairs because the floor below will not be flooded.
4058 // don't flood if ice lab because there's no mechanic for freezing
4059 // liquid floors.
4060 break;
4061 }
4062 auto fluid_type = one_in( 3 ) ? t_sewage : t_water_sh;
4063 for( int i = 0; i < 2; ++i ) {
4064 draw_rough_circle( [this, fluid_type]( const point & p ) {
4065 if( t_thconc_floor == ter( p ) || t_strconc_floor == ter( p ) ||
4066 t_thconc_floor_olight == ter( p ) ) {
4067 ter_set( p, fluid_type );
4068 } else if( has_flag_ter( "DOOR", p ) ) {
4069 // We want the actual debris, but not the rubble marker or dirt.
4070 make_rubble( { p, abs_sub.z } );
4071 ter_set( p, fluid_type );
4072 furn_set( p, f_null );
4073 }
4074 }, point( rng( 1, SEEX * 2 - 2 ), rng( 1, SEEY * 2 - 2 ) ), rng( 3, 6 ) );
4075 }
4076 break;
4077 }
4078 // toxic gas leaks and smoke-filled rooms.
4079 case 3:
4080 case 4: {
4081 bool is_toxic = one_in( 3 );
4082 for( int i = 0; i < SEEX * 2; i++ ) {
4083 for( int j = 0; j < SEEY * 2; j++ ) {
4084 if( one_in( 200 ) && ( t_thconc_floor == ter( point( i, j ) ) ||
4085 t_strconc_floor == ter( point( i, j ) ) ) ) {
4086 if( is_toxic ) {
4087 add_field( {i, j, abs_sub.z}, fd_gas_vent, 1 );
4088 } else {
4089 add_field( {i, j, abs_sub.z}, fd_smoke_vent, 2 );
4090 }
4091 }
4092 }
4093 }
4094 break;
4095 }
4096 // portal with an artifact effect.
4097 case 5: {
4098 tripoint center( rng( 6, SEEX * 2 - 7 ), rng( 6, SEEY * 2 - 7 ), abs_sub.z );
4099 std::vector<artifact_natural_property> valid_props = {
4106 };
4107 draw_rough_circle( [this]( const point & p ) {
4108 if( has_flag_ter( "GOES_DOWN", p ) ||
4109 has_flag_ter( "GOES_UP", p ) ||
4110 has_flag_ter( "CONSOLE", p ) ) {
4111 return; // spare stairs and consoles.
4112 }
4113 make_rubble( {p, abs_sub.z } );
4114 ter_set( p, t_thconc_floor );
4115 }, center.xy(), 4 );
4116 furn_set( center.xy(), f_null );
4118 create_anomaly( center, random_entry( valid_props ), false );
4119 break;
4120 }
4121 // radioactive accident.
4122 case 6: {
4123 tripoint center( rng( 6, SEEX * 2 - 7 ), rng( 6, SEEY * 2 - 7 ), abs_sub.z );
4124 if( has_flag_ter( "WALL", center.xy() ) ) {
4125 // just skip it, we don't want to risk embedding radiation out of sight.
4126 break;
4127 }
4128 draw_rough_circle( [this]( const point & p ) {
4129 set_radiation( p, 10 );
4130 }, center.xy(), rng( 7, 12 ) );
4131 draw_circle( [this]( const point & p ) {
4132 set_radiation( p, 20 );
4133 }, center.xy(), rng( 5, 8 ) );
4134 draw_circle( [this]( const point & p ) {
4135 set_radiation( p, 30 );
4136 }, center.xy(), rng( 2, 4 ) );
4137 draw_circle( [this]( const point & p ) {
4138 set_radiation( p, 50 );
4139 }, center.xy(), 1 );
4140 draw_circle( [this]( const point & p ) {
4141 if( has_flag_ter( "GOES_DOWN", p ) ||
4142 has_flag_ter( "GOES_UP", p ) ||
4143 has_flag_ter( "CONSOLE", p ) ) {
4144 return; // spare stairs and consoles.
4145 }
4146 make_rubble( {p, abs_sub.z } );
4147 ter_set( p, t_thconc_floor );
4148 }, center.xy(), 1 );
4149
4151 center.xy() + point_west, 1, true );
4153 center.xy() + point_west, 1, true );
4154
4155 // damaged mininuke/plut thrown past edge of rubble so the player can see it.
4156 int marker_x = center.x - 2 + 4 * rng( 0, 1 );
4157 int marker_y = center.y + rng( -2, 2 );
4158 if( one_in( 4 ) ) {
4159 spawn_item(
4160 point( marker_x, marker_y ), "mininuke", 1, 1, calendar::start_of_cataclysm, rng( 2, 4 )
4161 );
4162 } else {
4163 item newliquid( "plut_slurry_dense", calendar::start_of_cataclysm );
4164 newliquid.charges = 1;
4165 add_item_or_charges( tripoint( marker_x, marker_y, get_abs_sub().z ),
4166 newliquid );
4167 }
4168 break;
4169 }
4170 // portal with fungal invasion
4171 case 7: {
4172 for( int i = 0; i < EAST_EDGE; i++ ) {
4173 for( int j = 0; j < SOUTH_EDGE; j++ ) {
4174 // Create a mostly spread fungal area throughout entire lab.
4175 if( !one_in( 5 ) && ( has_flag( "FLAT", point( i, j ) ) ) ) {
4176 ter_set( point( i, j ), t_fungus_floor_in );
4177 if( has_flag_furn( "ORGANIC", point( i, j ) ) ) {
4178 furn_set( point( i, j ), f_fungal_clump );
4179 }
4180 } else if( has_flag_ter( "DOOR", point( i, j ) ) && !one_in( 5 ) ) {
4181 ter_set( point( i, j ), t_fungus_floor_in );
4182 } else if( has_flag_ter( "WALL", point( i, j ) ) && one_in( 3 ) ) {
4183 ter_set( point( i, j ), t_fungus_wall );
4184 }
4185 }
4186 }
4187 tripoint center( rng( 6, SEEX * 2 - 7 ), rng( 6, SEEY * 2 - 7 ), abs_sub.z );
4188
4189 // Make a portal surrounded by more dense fungal stuff and a fungaloid.
4190 draw_rough_circle( [this]( const point & p ) {
4191 if( has_flag_ter( "GOES_DOWN", p ) ||
4192 has_flag_ter( "GOES_UP", p ) ||
4193 has_flag_ter( "CONSOLE", p ) ) {
4194 return; // spare stairs and consoles.
4195 }
4196 if( has_flag_ter( "WALL", p ) ) {
4197 ter_set( p, t_fungus_wall );
4198 } else {
4200 if( one_in( 3 ) ) {
4202 } else if( one_in( 10 ) ) {
4203 ter_set( p, t_marloss );
4204 }
4205 }
4206 }, center.xy(), 3 );
4208 furn_set( center.xy(), f_null );
4210 place_spawns( GROUP_FUNGI_FUNGALOID, 1, center.xy() + point( -2, -2 ),
4211 center.xy() + point( 2, 2 ), 1, true );
4212
4213 break;
4214 }
4215 }
4216 }
4217 } else if( terrain_type == "lab_finale" || terrain_type == "ice_lab_finale" ||
4218 terrain_type == "central_lab_finale" || terrain_type == "tower_lab_finale" ) {
4219
4220 ice_lab = is_ot_match( "ice_lab", terrain_type, ot_match_type::prefix );
4221 central_lab = is_ot_match( "central_lab", terrain_type, ot_match_type::prefix );
4222 tower_lab = is_ot_match( "tower_lab", terrain_type, ot_match_type::prefix );
4223
4224 if( ice_lab ) {
4225 int temperature = -20 + 30 * dat.zlevel();
4227 set_temperature( p2 + point( SEEX, 0 ), temperature );
4228 set_temperature( p2 + point( 0, SEEY ), temperature );
4230 }
4231
4232 tw = is_ot_match( "lab", dat.north(), ot_match_type::contains ) ? 0 : 2;
4233 rw = is_ot_match( "lab", dat.east(), ot_match_type::contains ) ? 1 : 2;
4234 bw = is_ot_match( "lab", dat.south(), ot_match_type::contains ) ? 1 : 2;
4235 lw = is_ot_match( "lab", dat.west(), ot_match_type::contains ) ? 0 : 2;
4236
4237 const int hardcoded_finale_map_weight = 500; // weight of all hardcoded maps.
4238 // If you remove the usage of "lab_finale_1level" here, remove it from mapgen_factory::get_usages above as well.
4239 if( oter_mapgen.generate( dat, "lab_finale_1level", hardcoded_finale_map_weight ) ) {
4240 // If the map template hasn't handled borders, handle them in code.
4241 // Rotated maps cannot handle borders and have to be caught in code.
4242 // We determine if a border isn't handled by checking the east-facing
4243 // border space where the door normally is -- it should be a wall or door.
4244 tripoint east_border( 23, 11, abs_sub.z );
4245 if( !has_flag_ter( "WALL", east_border ) && !has_flag_ter( "DOOR", east_border ) ) {
4246 // TODO: create a ter_reset function that does ter_set, furn_set, and i_clear?
4247 ter_id lw_type = tower_lab ? t_reinforced_glass : t_concrete_wall;
4248 ter_id tw_type = tower_lab ? t_reinforced_glass : t_concrete_wall;
4249 ter_id rw_type = tower_lab && rw == 2 ? t_reinforced_glass : t_concrete_wall;
4250 ter_id bw_type = tower_lab && bw == 2 ? t_reinforced_glass : t_concrete_wall;
4251 for( int i = 0; i < SEEX * 2; i++ ) {
4252 ter_set( point( 23, i ), rw_type );
4253 furn_set( point( 23, i ), f_null );
4254 i_clear( tripoint( 23, i, get_abs_sub().z ) );
4255
4256 ter_set( point( i, 23 ), bw_type );
4257 furn_set( point( i, 23 ), f_null );
4258 i_clear( tripoint( i, 23, get_abs_sub().z ) );
4259
4260 if( lw == 2 ) {
4261 ter_set( point( 0, i ), lw_type );
4262 furn_set( point( 0, i ), f_null );
4263 i_clear( tripoint( 0, i, get_abs_sub().z ) );
4264 }
4265 if( tw == 2 ) {
4266 ter_set( point( i, 0 ), tw_type );
4267 furn_set( point( i, 0 ), f_null );
4268 i_clear( tripoint( i, 0, get_abs_sub().z ) );
4269 }
4270 }
4271 if( rw != 2 ) {
4272 ter_set( point( 23, 11 ), t_door_metal_c );
4273 ter_set( point( 23, 12 ), t_door_metal_c );
4274 }
4275 if( bw != 2 ) {
4276 ter_set( point( 11, 23 ), t_door_metal_c );
4277 ter_set( point( 12, 23 ), t_door_metal_c );
4278 }
4279 }
4280 } else { // then no json maps for lab_finale_1level were found
4281 // Start by setting up a large, empty room.
4282 for( int i = 0; i < SEEX * 2; i++ ) {
4283 for( int j = 0; j < SEEY * 2; j++ ) {
4284 if( i < lw || i > EAST_EDGE - rw ) {
4285 ter_set( point( i, j ), t_concrete_wall );
4286 } else if( j < tw || j > SOUTH_EDGE - bw ) {
4287 ter_set( point( i, j ), t_concrete_wall );
4288 } else {
4289 ter_set( point( i, j ), t_thconc_floor );
4290 }
4291 }
4292 }
4293 if( rw == 1 ) {
4296 }
4297 if( bw == 1 ) {
4300 }
4301
4302 int loot_variant; //only used for weapons testing variant.
4303 computer *tmpcomp = nullptr;
4304 switch( rng( 1, 5 ) ) {
4305 // Weapons testing - twice as common because it has 4 variants.
4306 case 1:
4307 case 2:
4308 loot_variant = rng( 1, 100 ); //The variants have a 67/22/7/4 split.
4309 place_spawns( GROUP_ROBOT_SECUBOT, 1, point( 6, 6 ), point( 6, 6 ), 1, true );
4310 place_spawns( GROUP_ROBOT_SECUBOT, 1, point( SEEX * 2 - 7, 6 ),
4311 point( SEEX * 2 - 7, 6 ), 1, true );
4312 place_spawns( GROUP_ROBOT_SECUBOT, 1, point( 6, SEEY * 2 - 7 ),
4313 point( 6, SEEY * 2 - 7 ), 1, true );
4314 place_spawns( GROUP_ROBOT_SECUBOT, 1, point( SEEX * 2 - 7, SEEY * 2 - 7 ),
4315 point( SEEX * 2 - 7, SEEY * 2 - 7 ), 1, true );
4316 spawn_item( point( SEEX - 4, SEEY - 2 ), "id_science" );
4317 if( loot_variant <= 96 ) {
4318 mtrap_set( this, point( SEEX - 3, SEEY - 3 ), tr_dissector );
4319 mtrap_set( this, point( SEEX + 2, SEEY - 3 ), tr_dissector );
4320 mtrap_set( this, point( SEEX - 3, SEEY + 2 ), tr_dissector );
4321 mtrap_set( this, point( SEEX + 2, SEEY + 2 ), tr_dissector );
4322 line( this, t_reinforced_glass, point( SEEX + 1, SEEY + 1 ), point( SEEX - 2, SEEY + 1 ) );
4323 line( this, t_reinforced_glass, point( SEEX - 2, SEEY ), point( SEEX - 2, SEEY - 2 ) );
4324 line( this, t_reinforced_glass, point( SEEX - 1, SEEY - 2 ), point( SEEX + 1, SEEY - 2 ) );
4325 ter_set( point( SEEX + 1, SEEY - 1 ), t_reinforced_glass );
4327 furn_set( point( SEEX - 1, SEEY - 1 ), f_table );
4328 furn_set( point( SEEX, SEEY - 1 ), f_table );
4329 furn_set( point( SEEX - 1, SEEY ), f_table );
4330 furn_set( point( SEEX, SEEY ), f_table );
4331 if( loot_variant <= 67 ) {
4332 spawn_item( point( SEEX, SEEY - 1 ), "UPS_off" );
4333 spawn_item( point( SEEX, SEEY - 1 ), "heavy_battery_cell" );
4334 spawn_item( point( SEEX - 1, SEEY ), "v29" );
4335 spawn_item( point( SEEX - 1, SEEY ), "laser_rifle", dice( 1, 0 ) );
4336 spawn_item( point( SEEX, SEEY ), "plasma_gun" );
4337 spawn_item( point( SEEX, SEEY ), "plasma" );
4338 spawn_item( point( SEEX - 1, SEEY ), "recipe_atomic_battery" );
4339 spawn_item( point( SEEX + 1, SEEY ), "plut_cell", rng( 8, 20 ) );
4340 } else if( loot_variant < 89 ) {
4341 spawn_item( point( SEEX - 1, SEEY - 1 ), "mininuke", dice( 3, 6 ) );
4342 spawn_item( point( SEEX, SEEY - 1 ), "mininuke", dice( 3, 6 ) );
4343 spawn_item( point( SEEX - 1, SEEY ), "mininuke", dice( 3, 6 ) );
4344 spawn_item( point( SEEX, SEEY ), "mininuke", dice( 3, 6 ) );
4345 spawn_item( point( SEEX, SEEY ), "recipe_atomic_battery" );
4346 spawn_item( point( SEEX + 1, SEEY ), "plut_cell", rng( 8, 20 ) );
4347 } else { // loot_variant between 90 and 96.
4348 spawn_item( point( SEEX - 1, SEEY - 1 ), "rm13_armor" );
4349 spawn_item( point( SEEX, SEEY - 1 ), "plut_cell" );
4350 spawn_item( point( SEEX - 1, SEEY ), "plut_cell" );
4351 spawn_item( point( SEEX, SEEY ), "recipe_caseless" );
4352 }
4353 } else { // 4% of the lab ends will be this weapons testing end.
4354 mtrap_set( this, point( SEEX - 4, SEEY - 3 ), tr_dissector );
4355 mtrap_set( this, point( SEEX + 3, SEEY - 3 ), tr_dissector );
4356 mtrap_set( this, point( SEEX - 4, SEEY + 2 ), tr_dissector );
4357 mtrap_set( this, point( SEEX + 3, SEEY + 2 ), tr_dissector );
4358
4359 furn_set( point( SEEX - 2, SEEY - 1 ), f_rack );
4360 furn_set( point( SEEX - 1, SEEY - 1 ), f_rack );
4361 furn_set( point( SEEX, SEEY - 1 ), f_rack );
4362 furn_set( point( SEEX + 1, SEEY - 1 ), f_rack );
4363 furn_set( point( SEEX - 2, SEEY ), f_rack );
4364 furn_set( point( SEEX - 1, SEEY ), f_rack );
4365 furn_set( point( SEEX, SEEY ), f_rack );
4366 furn_set( point( SEEX + 1, SEEY ), f_rack );
4367 line( this, t_reinforced_door_glass_c, point( SEEX - 2, SEEY - 2 ),
4368 point( SEEX + 1, SEEY - 2 ) );
4369 line( this, t_reinforced_door_glass_c, point( SEEX - 2, SEEY + 1 ),
4370 point( SEEX + 1, SEEY + 1 ) );
4371 line( this, t_reinforced_glass, point( SEEX - 3, SEEY - 2 ), point( SEEX - 3, SEEY + 1 ) );
4372 line( this, t_reinforced_glass, point( SEEX + 2, SEEY - 2 ), point( SEEX + 2, SEEY + 1 ) );
4373 place_items( item_group_id( "ammo_rare" ), 96, point( SEEX - 2, SEEY - 1 ),
4374 point( SEEX + 1, SEEY - 1 ), false, calendar::start_of_cataclysm );
4375 place_items( item_group_id( "guns_rare" ), 96, point( SEEX - 2, SEEY ), point( SEEX + 1, SEEY ),
4376 false,
4378 spawn_item( point( SEEX + 1, SEEY ), "plut_cell", rng( 1, 10 ) );
4379 }
4380 break;
4381 // Netherworld access
4382 case 3: {
4383 bool monsters_end = false;
4384 if( !one_in( 4 ) ) { // Trapped netherworld monsters
4385 monsters_end = true;
4386 tw = rng( SEEY + 3, SEEY + 5 );
4387 bw = tw + 4;
4388 lw = rng( SEEX - 6, SEEX - 2 );
4389 rw = lw + 6;
4390 for( int i = lw; i <= rw; i++ ) {
4391 for( int j = tw; j <= bw; j++ ) {
4392 if( j == tw || j == bw ) {
4393 if( ( i - lw ) % 2 == 0 ) {
4394 ter_set( point( i, j ), t_concrete_wall );
4395 } else {
4396 ter_set( point( i, j ), t_reinforced_glass );
4397 }
4398 } else if( ( i - lw ) % 2 == 0 ) {
4399 ter_set( point( i, j ), t_concrete_wall );
4400 } else if( j == tw + 2 ) {
4401 ter_set( point( i, j ), t_concrete_wall );
4402 } else { // Empty space holds monsters!
4403 place_spawns( GROUP_NETHER, 1, point( i, j ), point( i, j ), 1, true );
4404 }
4405 }
4406 }
4407 }
4408
4409 spawn_item( point( SEEX - 1, 8 ), "id_science" );
4410 tmpcomp = add_computer( tripoint( SEEX, 8, abs_sub.z ),
4411 _( "Sub-prime contact console" ), 7 );
4412 if( monsters_end ) { //only add these options when there are monsters.
4413 tmpcomp->add_option( _( "Terminate Specimens" ), COMPACT_TERMINATE, 2 );
4414 tmpcomp->add_option( _( "Release Specimens" ), COMPACT_RELEASE, 3 );
4415 }
4416 tmpcomp->add_option( _( "Toggle Portal" ), COMPACT_PORTAL, 8 );
4417 tmpcomp->add_option( _( "Activate Resonance Cascade" ), COMPACT_CASCADE, 10 );
4418 tmpcomp->add_failure( COMPFAIL_MANHACKS );
4419 tmpcomp->add_failure( COMPFAIL_SECUBOTS );
4420 tmpcomp->set_access_denied_msg(
4421 _( "ERROR! Access denied! Unauthorized access will be met with lethal force!" ) );
4422 ter_set( point( SEEX - 2, 4 ), t_radio_tower );
4423 ter_set( point( SEEX + 1, 4 ), t_radio_tower );
4424 ter_set( point( SEEX - 2, 7 ), t_radio_tower );
4425 ter_set( point( SEEX + 1, 7 ), t_radio_tower );
4426 }
4427 break;
4428
4429 // Bionics
4430 case 4: {
4431 place_spawns( GROUP_ROBOT_SECUBOT, 1, point( 6, 6 ), point( 6, 6 ), 1, true );
4432 place_spawns( GROUP_ROBOT_SECUBOT, 1, point( SEEX * 2 - 7, 6 ),
4433 point( SEEX * 2 - 7, 6 ), 1, true );
4434 place_spawns( GROUP_ROBOT_SECUBOT, 1, point( 6, SEEY * 2 - 7 ),
4435 point( 6, SEEY * 2 - 7 ), 1, true );
4436 place_spawns( GROUP_ROBOT_SECUBOT, 1, point( SEEX * 2 - 7, SEEY * 2 - 7 ),
4437 point( SEEX * 2 - 7, SEEY * 2 - 7 ), 1, true );
4438 mtrap_set( this, point( SEEX - 2, SEEY - 2 ), tr_dissector );
4439 mtrap_set( this, point( SEEX + 1, SEEY - 2 ), tr_dissector );
4440 mtrap_set( this, point( SEEX - 2, SEEY + 1 ), tr_dissector );
4441 mtrap_set( this, point( SEEX + 1, SEEY + 1 ), tr_dissector );
4442 square_furn( this, f_counter, point( SEEX - 1, SEEY - 1 ), point( SEEX, SEEY ) );
4443 int item_count = 0;
4444 while( item_count < 5 ) {
4445 item_count += place_items( item_group_id( "bionics" ), 75, point( SEEX - 1, SEEY - 1 ),
4446 point( SEEX, SEEY ), false, calendar::start_of_cataclysm ).size();
4447 }
4448 line( this, t_reinforced_glass, point( SEEX - 2, SEEY - 2 ), point( SEEX + 1, SEEY - 2 ) );
4449 line( this, t_reinforced_glass, point( SEEX - 2, SEEY + 1 ), point( SEEX + 1, SEEY + 1 ) );
4450 line( this, t_reinforced_glass, point( SEEX - 2, SEEY - 1 ), point( SEEX - 2, SEEY ) );
4451 line( this, t_reinforced_glass, point( SEEX + 1, SEEY - 1 ), point( SEEX + 1, SEEY ) );
4452 spawn_item( point( SEEX - 4, SEEY - 3 ), "id_science" );
4453 ter_set( point( SEEX - 3, SEEY - 3 ), t_console );
4454 tmpcomp = add_computer( tripoint( SEEX - 3, SEEY - 3, abs_sub.z ),
4455 _( "Bionic access" ), 3 );
4456 tmpcomp->add_option( _( "Manifest" ), COMPACT_LIST_BIONICS, 0 );
4457 tmpcomp->add_option( _( "Open Chambers" ), COMPACT_RELEASE, 5 );
4458 tmpcomp->add_failure( COMPFAIL_MANHACKS );
4459 tmpcomp->add_failure( COMPFAIL_SECUBOTS );
4460 tmpcomp->set_access_denied_msg(
4461 _( "ERROR! Access denied! Unauthorized access will be met with lethal force!" ) );
4462 }
4463 break;
4464
4465 // CVD Forge
4466 case 5:
4467 place_spawns( GROUP_ROBOT_SECUBOT, 1, point( 6, 6 ), point( 6, 6 ), 1, true );
4468 place_spawns( GROUP_ROBOT_SECUBOT, 1, point( SEEX * 2 - 7, 6 ),
4469 point( SEEX * 2 - 7, 6 ), 1, true );
4470 place_spawns( GROUP_ROBOT_SECUBOT, 1, point( 6, SEEY * 2 - 7 ),
4471 point( 6, SEEY * 2 - 7 ), 1, true );
4472 place_spawns( GROUP_ROBOT_SECUBOT, 1, point( SEEX * 2 - 7, SEEY * 2 - 7 ),
4473 point( SEEX * 2 - 7, SEEY * 2 - 7 ), 1, true );
4474 line( this, t_cvdbody, point( SEEX - 2, SEEY - 2 ), point( SEEX - 2, SEEY + 1 ) );
4475 line( this, t_cvdbody, point( SEEX - 1, SEEY - 2 ), point( SEEX - 1, SEEY + 1 ) );
4476 line( this, t_cvdbody, point( SEEX, SEEY - 1 ), point( SEEX, SEEY + 1 ) );
4477 line( this, t_cvdbody, point( SEEX + 1, SEEY - 2 ), point( SEEX + 1, SEEY + 1 ) );
4478 ter_set( point( SEEX, SEEY - 2 ), t_cvdmachine );
4479 spawn_item( point( SEEX, SEEY - 3 ), "id_science" );
4480 break;
4481 }
4482 } // end use_hardcoded_lab_finale
4483
4484 // Handle stairs in the unlikely case they are needed.
4485
4486 const auto maybe_insert_stairs = [this]( const oter_id & terrain, const ter_id & t_stair_type ) {
4487 if( is_ot_match( "stairs", terrain, ot_match_type::contains ) ) {
4488 const auto predicate = [this]( const tripoint & p ) {
4489 return ter( p ) == t_thconc_floor && furn( p ) == f_null &&
4490 tr_at( p ).is_null();
4491 };
4492 const auto range = points_in_rectangle( { 0, 0, abs_sub.z },
4493 { SEEX * 2 - 2, SEEY * 2 - 2, abs_sub.z } );
4494 if( const auto p = random_point( range, predicate ) ) {
4495 ter_set( *p, t_stair_type );
4496 }
4497 }
4498 };
4499 maybe_insert_stairs( dat.above(), t_stairs_up );
4500 maybe_insert_stairs( terrain_type, t_stairs_down );
4501
4502 int light_odds = 0;
4503 // central labs are always fully lit, other labs have half chance of some lights.
4504 if( central_lab ) {
4505 light_odds = 1;
4506 } else if( one_in( 2 ) ) {
4507 light_odds = std::pow( rng( 1, 12 ), 1.6 );
4508 }
4509 if( light_odds > 0 ) {
4510 for( int i = 0; i < SEEX * 2; i++ ) {
4511 for( int j = 0; j < SEEY * 2; j++ ) {
4512 if( !( ( i * j ) % 2 || ( i + j ) % 4 ) && one_in( light_odds ) ) {
4513 if( t_thconc_floor == ter( point( i, j ) ) || t_strconc_floor == ter( point( i, j ) ) ) {
4515 }
4516 }
4517 }
4518 }
4519 }
4520 }
4521}
void set_access_denied_msg(const std::string &new_msg)
Definition: computer.cpp:97
void add_failure(const computer_failure &failure)
Definition: computer.cpp:87
void add_option(const computer_option &opt)
Definition: computer.cpp:76
void set_temperature(const tripoint &p, int temperature)
Definition: map.cpp:4080
computer * add_computer(const tripoint &p, const std::string &name, int security)
Definition: mapgen.cpp:5790
void i_clear(const tripoint &p)
Definition: map.cpp:4128
std::vector< item * > place_items(const item_group_id &loc, int chance, const tripoint &p1, const tripoint &p2, bool ongrass, const time_point &turn, int magazine=0, int ammo=0)
Place items from item group in the rectangle f - t.
Definition: mapgen.cpp:5520
void trap_set(const tripoint &p, const trap_id &type)
Definition: map.cpp:5189
bool generate(mapgendata &dat, const std::string &key, const int hardcoded_weight=0) const
Definition: mapgen.cpp:343
int zlevel() const
Definition: mapgendata.h:99
@ COMPACT_RELEASE
Definition: computer.h:42
@ COMPACT_TERMINATE
Definition: computer.h:59
@ COMPACT_PORTAL
Definition: computer.h:40
@ COMPACT_CASCADE
Definition: computer.h:19
@ COMPACT_LIST_BIONICS
Definition: computer.h:32
@ COMPFAIL_SECUBOTS
Definition: computer.h:77
@ COMPFAIL_MANHACKS
Definition: computer.h:74
void draw_rough_circle(std::function< void(const point &)>set, const point &p, int rad)
@ prefix
Definition: enums.h:79
@ contains
Definition: enums.h:83
field_type_id fd_gas_vent
Definition: field_type.cpp:350
field_type_id fd_smoke_vent
Definition: field_type.cpp:385
ter_id t_door_glass_frosted_c
Definition: mapdata.cpp:664
ter_id t_cvdmachine
Definition: mapdata.cpp:712
ter_id t_slime
Definition: mapdata.cpp:637
ter_id t_strconc_floor
Definition: mapdata.cpp:631
furn_id f_table
Definition: mapdata.cpp:1104
furn_id f_fungal_clump
Definition: mapdata.cpp:1116
ter_id t_cvdbody
Definition: mapdata.cpp:712
ter_id t_radio_tower
Definition: mapdata.cpp:703
ter_id t_fungus_floor_in
Definition: mapdata.cpp:690
furn_id f_counter
Definition: mapdata.cpp:1105
furn_id f_rack
Definition: mapdata.cpp:1107
ter_id t_fungus_wall
Definition: mapdata.cpp:690
ter_id t_reinforced_glass
Definition: mapdata.cpp:650
ter_id t_concrete_wall
Definition: mapdata.cpp:646
ter_id t_floor
Definition: mapdata.cpp:632
ter_id t_thconc_floor_olight
Definition: mapdata.cpp:631
ter_id t_bars
Definition: mapdata.cpp:653
ter_id t_thconc_floor
Definition: mapdata.cpp:631
furn_id f_rubble_rock
Definition: mapdata.cpp:1097
ter_id t_stairs_up
Definition: mapdata.cpp:718
ter_id t_stairs_down
Definition: mapdata.cpp:718
ter_id t_marloss
Definition: mapdata.cpp:690
ter_id t_door_metal_locked
Definition: mapdata.cpp:662
ter_id t_card_science
Definition: mapdata.cpp:722
ter_id t_reinforced_door_glass_c
Definition: mapdata.cpp:652
furn_id f_flower_fungal
Definition: mapdata.cpp:1116
void square_furn(map *m, const furn_id &type, const point &p1, const point &p2)
Definition: mapgen.cpp:6482
static const mongroup_id GROUP_ROBOT_SECUBOT("GROUP_ROBOT_SECUBOT")
static const mongroup_id GROUP_HAZMATBOT("GROUP_HAZMATBOT")
static const mongroup_id GROUP_NETHER("GROUP_NETHER")
static const mongroup_id GROUP_TURRET("GROUP_TURRET")
void line(map *m, const ter_id &type, const point &p1, const point &p2)
Definition: mapgen.cpp:6462
static void science_room(map *m, const point &p1, const point &p2, int z, int rotate)
Definition: mapgen.cpp:5956
const int SOUTH_EDGE
Definition: mapgen.cpp:2931
const int EAST_EDGE
Definition: mapgen.cpp:2932
static mapgen_factory oter_mapgen
Definition: mapgen.cpp:352
static const mongroup_id GROUP_FUNGI_FUNGALOID("GROUP_FUNGI_FUNGALOID")
static const mongroup_id GROUP_LAB("GROUP_LAB")
static const trap_str_id tr_portal("tr_portal")
static const trap_str_id tr_dissector("tr_dissector")
const time_point & start_of_cataclysm
Definition: calendar.cpp:33
quantity< int, temperature_in_millidegree_celsius_tag > temperature
std::pair< item, int > item_count
Definition: pickup.cpp:63
int dice(int number, int sides)
Definition: rng.cpp:85
V random_entry(const C &container, D default_value)
Returns a random entry in the container.
Definition: rng.h:88

References _, mapgendata::above(), abs_sub, add_computer(), computer::add_failure(), add_field(), add_item_or_charges(), computer::add_option(), ARTPROP_BREATHING, ARTPROP_CRACKLING, ARTPROP_GLOWING, ARTPROP_SCALED, ARTPROP_WARM, ARTPROP_WHISPERING, center, item::charges, COMPACT_CASCADE, COMPACT_LIST_BIONICS, COMPACT_PORTAL, COMPACT_RELEASE, COMPACT_TERMINATE, COMPFAIL_MANHACKS, COMPFAIL_SECUBOTS, connects_to(), contains, create_anomaly(), debugmsg, destroy(), dice(), draw_circle(), draw_rough_circle(), mapgendata::east(), EAST_EDGE, f_counter, f_flower_fungal, f_fungal_clump, f_null, f_rack, f_rubble_rock, f_table, fd_gas_vent, fd_smoke_vent, furn(), furn_set(), mapgen_factory::generate(), get_abs_sub(), GROUP_FUNGI_FUNGALOID, GROUP_HAZMATBOT, GROUP_LAB, GROUP_NETHER, GROUP_ROBOT_SECUBOT, GROUP_TURRET, has_flag(), has_flag_furn(), has_flag_ter(), i_clear(), trap::is_null(), is_ot_match(), line(), make_rubble(), mtrap_set(), mapgendata::north(), one_in(), oter_mapgen, place_items(), place_spawns(), point_west, point_zero, points_in_rectangle(), prefix, random_entry(), random_point(), rng(), rotate(), science_room(), SEEX, SEEY, computer::set_access_denied_msg(), set_radiation(), set_temperature(), mapgendata::south(), SOUTH_EDGE, spawn_item(), square_furn(), calendar::start_of_cataclysm, t_bars, t_card_science, t_concrete_wall, t_console, t_cvdbody, t_cvdmachine, t_dirt, t_door_glass_frosted_c, t_door_metal_c, t_door_metal_locked, t_floor, t_fungus_floor_in, t_fungus_wall, t_marloss, t_radio_tower, t_reinforced_door_glass_c, t_reinforced_glass, t_rock_floor, t_sewage, t_slime, t_stairs_down, t_stairs_up, t_strconc_floor, t_thconc_floor, t_thconc_floor_olight, t_water_sh, ter(), ter_set(), terrain, mapgendata::terrain_type(), tr_at(), tr_dissector, tr_portal, trap_set(), type, mapgendata::west(), tripoint::z, and mapgendata::zlevel().

Referenced by draw_map().

◆ draw_line_furn()

void map::draw_line_furn ( const furn_id type,
const point p1,
const point p2 
)

Definition at line 8359 of file map.cpp.

8360{
8361 draw_line( [this, type]( const point & p ) {
8362 this->furn_set( p, type );
8363 }, p1, p2 );
8364}
void draw_line(std::function< void(const point &)>set, const point &p1, const point &p2)

References draw_line(), furn_set(), and type.

Referenced by jmapgen_setmap::apply(), and line_furn().

◆ draw_line_ter()

void map::draw_line_ter ( const ter_id type,
const point p1,
const point p2 
)

Definition at line 8352 of file map.cpp.

8353{
8354 draw_line( [this, type]( const point & p ) {
8355 this->ter_set( p, type );
8356 }, p1, p2 );
8357}

References draw_line(), ter_set(), and type.

Referenced by jmapgen_setmap::apply(), and line().

◆ draw_map()

void map::draw_map ( mapgendata dat)
protected

Definition at line 2891 of file mapgen.cpp.

2892{
2893 const oter_id &terrain_type = dat.terrain_type();
2894 const std::string function_key = terrain_type->get_mapgen_id();
2895 bool found = true;
2896
2897 const bool generated = run_mapgen_func( function_key, dat );
2898
2899 if( !generated ) {
2900 if( is_ot_match( "slimepit", terrain_type, ot_match_type::prefix ) ||
2901 is_ot_match( "slime_pit", terrain_type, ot_match_type::prefix ) ) {
2902 draw_slimepit( dat );
2903 } else if( is_ot_match( "triffid", terrain_type, ot_match_type::prefix ) ) {
2904 draw_triffid( dat );
2905 } else if( is_ot_match( "office", terrain_type, ot_match_type::prefix ) ) {
2906 draw_office_tower( dat );
2907 } else if( is_ot_match( "temple", terrain_type, ot_match_type::prefix ) ) {
2908 draw_temple( dat );
2909 } else if( is_ot_match( "mine", terrain_type, ot_match_type::prefix ) ) {
2910 draw_mine( dat );
2911 } else if( is_ot_match( "anthill", terrain_type, ot_match_type::contains ) ) {
2912 draw_anthill( dat );
2913 } else if( is_ot_match( "lab", terrain_type, ot_match_type::contains ) ) {
2914 draw_lab( dat );
2915 } else {
2916 found = false;
2917 }
2918 }
2919
2920 if( !found ) {
2921 // not one of the hardcoded ones!
2922 // load from JSON???
2923 debugmsg( "Error: tried to generate map for omtype %s, \"%s\" (id_mapgen %s)",
2924 terrain_type.id().c_str(), terrain_type->get_name(), function_key.c_str() );
2925 fill_background( this, t_floor );
2926 }
2927
2928 draw_connections( dat );
2929}
void draw_office_tower(mapgendata &dat)
Definition: mapgen.cpp:2934
void draw_mine(mapgendata &dat)
Definition: mapgen.cpp:4769
void draw_triffid(mapgendata &dat)
Definition: mapgen.cpp:5094
void draw_anthill(mapgendata &dat)
Definition: mapgen.cpp:5032
void draw_slimepit(mapgendata &dat)
Definition: mapgen.cpp:5050
void draw_lab(mapgendata &dat)
Definition: mapgen.cpp:3522
void draw_connections(mapgendata &dat)
Definition: mapgen.cpp:5242
void draw_temple(mapgendata &dat)
Definition: mapgen.cpp:4523
void fill_background(map *m, const ter_id &type)
Definition: mapgen.cpp:6470
bool run_mapgen_func(const std::string &mapgen_id, mapgendata &dat)
Definition: mapgen.cpp:6694
std::string get_name() const
Definition: omdata.h:205
std::string get_mapgen_id() const
Definition: overmap.cpp:797

References string_id< T >::c_str(), contains, debugmsg, draw_anthill(), draw_connections(), draw_lab(), draw_mine(), draw_office_tower(), draw_slimepit(), draw_temple(), draw_triffid(), fill_background(), oter_t::get_mapgen_id(), oter_t::get_name(), int_id< T >::id(), is_ot_match(), prefix, run_mapgen_func(), t_floor, and mapgendata::terrain_type().

Referenced by generate().

◆ draw_maptile()

bool map::draw_maptile ( const catacurses::window w,
const tripoint p,
const maptile tile,
const drawsq_params params 
) const
private

Internal version of the drawsq.

Keeps a cached maptile for less re-getting. Returns false if it has drawn all it should, true if draw_from_above should be called after.

Definition at line 5877 of file map.cpp.

5879{
5880 drawsq_params param = params;
5881 nc_color tercol;
5882 const ter_t &curr_ter = curr_maptile.get_ter_t();
5883 const furn_t &curr_furn = curr_maptile.get_furn_t();
5884 const trap &curr_trap = curr_maptile.get_trap().obj();
5885 const field &curr_field = curr_maptile.get_field();
5886 int sym;
5887 bool hi = false;
5888 bool graf = false;
5889 bool draw_item_sym = false;
5890
5891 int terrain_sym;
5892 if( curr_ter.has_flag( TFLAG_AUTO_WALL_SYMBOL ) ) {
5893 terrain_sym = determine_wall_corner( p );
5894 } else {
5895 terrain_sym = curr_ter.symbol();
5896 }
5897
5898 if( curr_furn.id ) {
5899 sym = curr_furn.symbol();
5900 tercol = curr_furn.color();
5901 } else {
5902 sym = terrain_sym;
5903 tercol = curr_ter.color();
5904 }
5905 if( curr_ter.has_flag( TFLAG_SWIMMABLE ) && curr_ter.has_flag( TFLAG_DEEP_WATER ) &&
5906 !g->u.is_underwater() ) {
5907 param.show_items( false ); // Can only see underwater items if WE are underwater
5908 }
5909 // If there's a trap here, and we have sufficient perception, draw that instead
5910 if( curr_trap.can_see( p, g->u ) ) {
5911 tercol = curr_trap.color;
5912 if( curr_trap.sym == '%' ) {
5913 switch( rng( 1, 5 ) ) {
5914 case 1:
5915 sym = '*';
5916 break;
5917 case 2:
5918 sym = '0';
5919 break;
5920 case 3:
5921 sym = '8';
5922 break;
5923 case 4:
5924 sym = '&';
5925 break;
5926 case 5:
5927 sym = '+';
5928 break;
5929 }
5930 } else {
5931 sym = curr_trap.sym;
5932 }
5933 }
5934 if( curr_field.field_count() > 0 ) {
5935 const field_type_id &fid = curr_field.displayed_field_type();
5936 const field_entry *fe = curr_field.find_field( fid );
5937 const auto field_symbol = fid->get_symbol();
5938 if( field_symbol == "&" || fe == nullptr ) {
5939 // Do nothing, a '&' indicates invisible fields.
5940 } else if( field_symbol == "*" ) {
5941 // A random symbol.
5942 switch( rng( 1, 5 ) ) {
5943 case 1:
5944 sym = '*';
5945 break;
5946 case 2:
5947 sym = '0';
5948 break;
5949 case 3:
5950 sym = '8';
5951 break;
5952 case 4:
5953 sym = '&';
5954 break;
5955 case 5:
5956 sym = '+';
5957 break;
5958 }
5959 } else {
5960 // A field symbol '%' indicates the field should not hide
5961 // items/terrain. When the symbol is not '%' it will
5962 // hide items (the color is still inverted if there are items,
5963 // but the tile symbol is not changed).
5964 // draw_item_sym indicates that the item symbol should be used
5965 // even if sym is not '.'.
5966 // As we don't know at this stage if there are any items
5967 // (that are visible to the player!), we always set the symbol.
5968 // If there are items and the field does not hide them,
5969 // the code handling items will override it.
5970 draw_item_sym = ( field_symbol == "'%" );
5971 // If field display_priority is > 1, and the field is set to hide items,
5972 //draw the field as it obscures what's under it.
5973 if( ( field_symbol != "%" && fid.obj().priority > 1 ) || ( field_symbol != "%" &&
5974 sym == '.' ) ) {
5975 // default terrain '.' and
5976 // non-default field symbol -> field symbol overrides terrain
5977 sym = field_symbol[0];
5978 }
5979 tercol = fe->color();
5980 }
5981 }
5982
5983 // TODO: change the local variable sym to std::string and use it instead of this hack.
5984 // Currently this are different variables because terrain/... uses int as symbol type and
5985 // item now use string. Ideally they should all be strings.
5986 std::string item_sym;
5987
5988 // If there are items here, draw those instead
5989 if( param.show_items() && curr_maptile.get_item_count() > 0 && sees_some_items( p, g->u ) ) {
5990 // if there's furniture/terrain/trap/fields (sym!='.')
5991 // and we should not override it, then only highlight the square
5992 if( sym != '.' && sym != '%' && !draw_item_sym ) {
5993 hi = true;
5994 } else {
5995 // otherwise override with the symbol of the last item
5996 item_sym = curr_maptile.get_uppermost_item().symbol();
5997 if( !draw_item_sym ) {
5998 tercol = curr_maptile.get_uppermost_item().color();
5999 }
6000 if( curr_maptile.get_item_count() > 1 ) {
6001 param.highlight( !param.highlight() );
6002 }
6003 }
6004 }
6005
6006 int memory_sym = sym;
6007 int veh_part = 0;
6008 const vehicle *veh = veh_at_internal( p, veh_part );
6009 if( veh != nullptr ) {
6010 sym = special_symbol( veh->face.dir_symbol( veh->part_sym( veh_part ) ) );
6011 tercol = veh->part_color( veh_part );
6012 item_sym.clear(); // clear the item symbol so `sym` is used instead.
6013
6014 if( !veh->forward_velocity() && !veh->player_in_control( g->u ) ) {
6015 memory_sym = sym;
6016 }
6017 }
6018
6019 if( param.memorize() && check_and_set_seen_cache( p ) ) {
6020 g->u.memorize_symbol( getabs( p ), memory_sym );
6021 }
6022
6023 // If there's graffiti here, change background color
6024 if( curr_maptile.has_graffiti() ) {
6025 graf = true;
6026 }
6027
6028 const auto u_vision = g->u.get_vision_modes();
6029 if( u_vision[BOOMERED] ) {
6030 tercol = c_magenta;
6031 } else if( u_vision[NV_GOGGLES] ) {
6032 tercol = param.bright_light() ? c_white : c_light_green;
6033 } else if( param.low_light() ) {
6034 tercol = c_dark_gray;
6035 } else if( u_vision[DARKNESS] ) {
6036 tercol = c_dark_gray;
6037 }
6038
6039 if( param.highlight() ) {
6040 tercol = invert_color( tercol );
6041 } else if( hi ) {
6042 tercol = hilite( tercol );
6043 } else if( graf ) {
6044 tercol = red_background( tercol );
6045 }
6046
6047 if( item_sym.empty() && sym == ' ' ) {
6048 if( !zlevels || p.z <= -OVERMAP_DEPTH || !curr_ter.has_flag( TFLAG_NO_FLOOR ) ) {
6049 // Print filler symbol
6050 sym = ' ';
6051 tercol = c_black;
6052 } else {
6053 // Draw tile underneath this one instead
6054 return false;
6055 }
6056 }
6057
6058 if( params.output() ) {
6059 if( item_sym.empty() ) {
6060 wputch( w, tercol, sym );
6061 } else {
6062 wprintz( w, tercol, item_sym );
6063 }
6064 }
6065 return true;
6066}
nc_color color() const
Definition: field.cpp:94
field_entry * find_field(const field_type_id &field_type_to_find)
Returns a field entry corresponding to the field_type_id parameter passed in.
Definition: field.cpp:153
field_type_id displayed_field_type() const
Returns field type that should be drawn.
Definition: field.cpp:275
unsigned int field_count() const
Definition: field.cpp:246
bool check_and_set_seen_cache(const tripoint &p) const
Definition: map.h:486
bool sees_some_items(const tripoint &p, const Creature &who) const
Check if creature can see some items at p.
Definition: map.cpp:4736
nc_color part_color(int p, bool exact=false) const
bool player_in_control(const Character &p) const
Definition: vehicle.cpp:277
float forward_velocity() const
nc_color red_background(const nc_color &c)
Definition: color.cpp:515
nc_color hilite(const nc_color &c)
Definition: color.cpp:509
@ TFLAG_SWIMMABLE
Definition: mapdata.h:279
void wprintz(const catacurses::window &w, const nc_color &FG, const std::string &text)
Definition: output.cpp:2043
constexpr drawsq_params & show_items(bool v)
Whether to draw items on the tile.
Definition: map.h:212
int priority
Definition: field_type.h:176
std::string get_symbol(int level=0) const
Definition: field_type.h:195
furn_str_id id
Definition: mapdata.h:496
nc_color color
Definition: trap.h:93
int sym
Definition: trap.h:92

References BOOMERED, drawsq_params::bright_light(), c_black, c_dark_gray, c_light_green, c_magenta, c_white, trap::can_see(), check_and_set_seen_cache(), field_entry::color(), item::color(), map_data_common_t::color(), trap::color, DARKNESS, determine_wall_corner(), tileray::dir_symbol(), field::displayed_field_type(), vehicle::face, field::field_count(), field::find_field(), vehicle::forward_velocity(), g, maptile::get_field(), maptile::get_furn_t(), maptile::get_item_count(), field_type::get_symbol(), maptile::get_ter_t(), maptile::get_trap(), maptile::get_uppermost_item(), getabs(), map_data_common_t::has_flag(), maptile::has_graffiti(), drawsq_params::highlight(), hilite(), furn_t::id, invert_color(), drawsq_params::low_light(), drawsq_params::memorize(), NV_GOGGLES, int_id< T >::obj(), drawsq_params::output(), OVERMAP_DEPTH, vehicle::part_color(), vehicle::part_sym(), vehicle::player_in_control(), field_type::priority, red_background(), rng(), sees_some_items(), drawsq_params::show_items(), special_symbol(), trap::sym, item::symbol(), map_data_common_t::symbol(), TFLAG_AUTO_WALL_SYMBOL, TFLAG_DEEP_WATER, TFLAG_NO_FLOOR, TFLAG_SWIMMABLE, veh_at_internal(), wprintz(), wputch(), tripoint::z, and zlevels.

Referenced by draw(), and drawsq().

◆ draw_mine()

void map::draw_mine ( mapgendata dat)
protected

Definition at line 4769 of file mapgen.cpp.

4770{
4771 const oter_id &terrain_type = dat.terrain_type();
4772 if( terrain_type == "mine" || terrain_type == "mine_down" ) {
4773 if( is_ot_match( "mine", dat.north(), ot_match_type::prefix ) ) {
4774 dat.n_fac = ( one_in( 10 ) ? 0 : -2 );
4775 } else {
4776 dat.n_fac = 4;
4777 }
4778 if( is_ot_match( "mine", dat.east(), ot_match_type::prefix ) ) {
4779 dat.e_fac = ( one_in( 10 ) ? 0 : -2 );
4780 } else {
4781 dat.e_fac = 4;
4782 }
4783 if( is_ot_match( "mine", dat.south(), ot_match_type::prefix ) ) {
4784 dat.s_fac = ( one_in( 10 ) ? 0 : -2 );
4785 } else {
4786 dat.s_fac = 4;
4787 }
4788 if( is_ot_match( "mine", dat.west(), ot_match_type::prefix ) ) {
4789 dat.w_fac = ( one_in( 10 ) ? 0 : -2 );
4790 } else {
4791 dat.w_fac = 4;
4792 }
4793
4794 for( int i = 0; i < SEEX * 2; i++ ) {
4795 for( int j = 0; j < SEEY * 2; j++ ) {
4796 if( i >= dat.w_fac + rng( 0, 2 ) && i <= EAST_EDGE - dat.e_fac - rng( 0, 2 ) &&
4797 j >= dat.n_fac + rng( 0, 2 ) && j <= SOUTH_EDGE - dat.s_fac - rng( 0, 2 ) &&
4798 i + j >= 4 && ( SEEX * 2 - i ) + ( SEEY * 2 - j ) >= 6 ) {
4799 ter_set( point( i, j ), t_rock_floor );
4800 } else {
4801 ter_set( point( i, j ), t_rock );
4802 }
4803 }
4804 }
4805
4806 // Not an entrance; maybe some hazards!
4807 switch( rng( 0, 4 ) ) {
4808 case 0:
4809 break; // Nothing! Lucky!
4810
4811 case 1: {
4812 // Toxic gas
4813 point gas_vent_location( rng( 9, 14 ), rng( 9, 14 ) );
4814 ter_set( point( gas_vent_location ), t_rock );
4815 add_field( { gas_vent_location, abs_sub.z }, fd_gas_vent, 2 );
4816 }
4817 break;
4818
4819 case 2: {
4820 // Lava
4821 point start_location( rng( 6, SEEX ), rng( 6, SEEY ) );
4822 point end_location( rng( SEEX + 1, SEEX * 2 - 7 ), rng( SEEY + 1, SEEY * 2 - 7 ) );
4823 const int num = rng( 2, 4 );
4824 for( int i = 0; i < num; i++ ) {
4825 int lx1 = start_location.x + rng( -1, 1 );
4826 int lx2 = end_location.x + rng( -1, 1 );
4827 int ly1 = start_location.y + rng( -1, 1 );
4828 int ly2 = end_location.y + rng( -1, 1 );
4829 line( this, t_lava, point( lx1, ly1 ), point( lx2, ly2 ) );
4830 }
4831 }
4832 break;
4833
4834 case 3: {
4835 // Wrecked equipment
4836 point wreck_location( rng( 9, 14 ), rng( 9, 14 ) );
4837 for( int i = wreck_location.x - 3; i < wreck_location.x + 3; i++ ) {
4838 for( int j = wreck_location.y - 3; j < wreck_location.y + 3; j++ ) {
4839 if( !one_in( 4 ) ) {
4840 make_rubble( tripoint( i, j, abs_sub.z ), f_wreckage, true );
4841 }
4842 }
4843 }
4844 place_items( item_group_id( "wreckage" ), 70, wreck_location + point( -3, -3 ),
4845 wreck_location + point( 2, 2 ), false, calendar::start_of_cataclysm );
4846 }
4847 break;
4848
4849 case 4: {
4850 // Dead miners
4851 const int num_bodies = rng( 4, 8 );
4852 for( int i = 0; i < num_bodies; i++ ) {
4853 if( const auto body = random_point( *this, [this]( const tripoint & p ) {
4854 return move_cost( p ) == 2;
4855 } ) ) {
4856 add_item( *body, item::make_corpse() );
4857 place_items( item_group_id( "mine_equipment" ), 60, *body, *body,
4859 }
4860 }
4861 }
4862 break;
4863
4864 }
4865
4866 if( terrain_type == "mine_down" ) { // Don't forget to build a slope down!
4867 std::vector<direction> open;
4868 if( dat.n_fac == 4 ) {
4869 open.push_back( direction::NORTH );
4870 }
4871 if( dat.e_fac == 4 ) {
4872 open.push_back( direction::EAST );
4873 }
4874 if( dat.s_fac == 4 ) {
4875 open.push_back( direction::SOUTH );
4876 }
4877 if( dat.w_fac == 4 ) {
4878 open.push_back( direction::WEST );
4879 }
4880
4881 if( open.empty() ) { // We'll have to build it in the center
4882 int tries = 0;
4883 point p;
4884 bool okay = true;
4885 do {
4886 p.x = rng( SEEX - 6, SEEX + 1 );
4887 p.y = rng( SEEY - 6, SEEY + 1 );
4888 okay = true;
4889 for( int i = p.x; ( i <= p.x + 5 ) && okay; i++ ) {
4890 for( int j = p.y; ( j <= p.y + 5 ) && okay; j++ ) {
4891 if( ter( point( i, j ) ) != t_rock_floor ) {
4892 okay = false;
4893 }
4894 }
4895 }
4896 if( !okay ) {
4897 tries++;
4898 }
4899 } while( !okay && tries < 10 );
4900 if( tries == 10 ) { // Clear the area around the slope down
4901 square( this, t_rock_floor, p, p + point( 5, 5 ) );
4902 }
4903 // NOLINTNEXTLINE(cata-use-named-point-constants)
4904 square( this, t_slope_down, p + point( 1, 1 ), p + point( 2, 2 ) );
4905 } else { // We can build against a wall
4906 switch( random_entry( open ) ) {
4907 case direction::NORTH:
4908 square( this, t_rock_floor, point( SEEX - 3, 6 ), point( SEEX + 2, SEEY ) );
4909 line( this, t_slope_down, point( SEEX - 2, 6 ), point( SEEX + 1, 6 ) );
4910 break;
4911 case direction::EAST:
4912 square( this, t_rock_floor, point( SEEX + 1, SEEY - 3 ), point( SEEX * 2 - 7, SEEY + 2 ) );
4913 line( this, t_slope_down, point( SEEX * 2 - 7, SEEY - 2 ), point( SEEX * 2 - 7, SEEY + 1 ) );
4914 break;
4915 case direction::SOUTH:
4916 square( this, t_rock_floor, point( SEEX - 3, SEEY + 1 ), point( SEEX + 2, SEEY * 2 - 7 ) );
4917 line( this, t_slope_down, point( SEEX - 2, SEEY * 2 - 7 ), point( SEEX + 1, SEEY * 2 - 7 ) );
4918 break;
4919 case direction::WEST:
4920 square( this, t_rock_floor, point( 6, SEEY - 3 ), point( SEEX, SEEY + 2 ) );
4921 line( this, t_slope_down, point( 6, SEEY - 2 ), point( 6, SEEY + 1 ) );
4922 break;
4923 default:
4924 break;
4925 }
4926 }
4927 } // Done building a slope down
4928
4929 if( dat.above() == "mine_down" ) { // Don't forget to build a slope up!
4930 std::vector<direction> open;
4931 if( dat.n_fac == 6 && ter( point( SEEX, 6 ) ) != t_slope_down ) {
4932 open.push_back( direction::NORTH );
4933 }
4934 if( dat.e_fac == 6 && ter( point( SEEX * 2 - 7, SEEY ) ) != t_slope_down ) {
4935 open.push_back( direction::EAST );
4936 }
4937 if( dat.s_fac == 6 && ter( point( SEEX, SEEY * 2 - 7 ) ) != t_slope_down ) {
4938 open.push_back( direction::SOUTH );
4939 }
4940 if( dat.w_fac == 6 && ter( point( 6, SEEY ) ) != t_slope_down ) {
4941 open.push_back( direction::WEST );
4942 }
4943
4944 if( open.empty() ) { // We'll have to build it in the center
4945 int tries = 0;
4946 point p;
4947 bool okay = true;
4948 do {
4949 p.x = rng( SEEX - 6, SEEX + 1 );
4950 p.y = rng( SEEY - 6, SEEY + 1 );
4951 okay = true;
4952 for( int i = p.x; ( i <= p.x + 5 ) && okay; i++ ) {
4953 for( int j = p.y; ( j <= p.y + 5 ) && okay; j++ ) {
4954 if( ter( point( i, j ) ) != t_rock_floor ) {
4955 okay = false;
4956 }
4957 }
4958 }
4959 if( !okay ) {
4960 tries++;
4961 }
4962 } while( !okay && tries < 10 );
4963 if( tries == 10 ) { // Clear the area around the slope down
4964 square( this, t_rock_floor, p, p + point( 5, 5 ) );
4965 }
4966 // NOLINTNEXTLINE(cata-use-named-point-constants)
4967 square( this, t_slope_up, p + point( 1, 1 ), p + point( 2, 2 ) );
4968
4969 } else { // We can build against a wall
4970 switch( random_entry( open ) ) {
4971 case direction::NORTH:
4972 line( this, t_slope_up, point( SEEX - 2, 6 ), point( SEEX + 1, 6 ) );
4973 break;
4974 case direction::EAST:
4975 line( this, t_slope_up, point( SEEX * 2 - 7, SEEY - 2 ), point( SEEX * 2 - 7, SEEY + 1 ) );
4976 break;
4977 case direction::SOUTH:
4978 line( this, t_slope_up, point( SEEX - 2, SEEY * 2 - 7 ), point( SEEX + 1, SEEY * 2 - 7 ) );
4979 break;
4980 case direction::WEST:
4981 line( this, t_slope_up, point( 6, SEEY - 2 ), point( 6, SEEY + 1 ) );
4982 break;
4983 default:
4984 break;
4985 }
4986 }
4987 } // Done building a slope up
4988 } else if( terrain_type == "mine_finale" ) {
4989 // Set up the basic chamber
4990 for( int i = 0; i < SEEX * 2; i++ ) {
4991 for( int j = 0; j < SEEY * 2; j++ ) {
4992 if( i > rng( 1, 3 ) && i < SEEX * 2 - rng( 2, 4 ) &&
4993 j > rng( 1, 3 ) && j < SEEY * 2 - rng( 2, 4 ) ) {
4994 ter_set( point( i, j ), t_rock_floor );
4995 } else {
4996 ter_set( point( i, j ), t_rock );
4997 }
4998 }
4999 }
5000
5001 // Now draw the entrance(s)
5002 if( dat.north() == "mine" ) {
5003 square( this, t_rock_floor, point( SEEX, 0 ), point( SEEX + 1, 3 ) );
5004 }
5005
5006 if( dat.east() == "mine" ) {
5007 square( this, t_rock_floor, point( SEEX * 2 - 4, SEEY ), point( EAST_EDGE, SEEY + 1 ) );
5008 }
5009
5010 if( dat.south() == "mine" ) {
5011 square( this, t_rock_floor, point( SEEX, SEEY * 2 - 4 ), point( SEEX + 1, SOUTH_EDGE ) );
5012 }
5013
5014 if( dat.west() == "mine" ) {
5015 square( this, t_rock_floor, point( 0, SEEY ), point( 3, SEEY + 1 ) );
5016 }
5017
5018 // Now, pick and generate a type of finale!
5019 // The Thing dog
5020 const int num_bodies = rng( 4, 8 );
5021 for( int i = 0; i < num_bodies; i++ ) {
5022 point p3( rng( 4, SEEX * 2 - 5 ), rng( 4, SEEX * 2 - 5 ) );
5023 add_item( p3, item::make_corpse() );
5024 place_items( item_group_id( "mine_equipment" ), 60, p3,
5025 p3, false, calendar::start_of_cataclysm );
5026 }
5027 place_spawns( GROUP_DOG_THING, 1, point( SEEX, SEEX ), point( SEEX + 1, SEEX + 1 ), 1, true, true );
5028 spawn_artifact( tripoint( rng( SEEX, SEEX + 1 ), rng( SEEY, SEEY + 1 ), abs_sub.z ) );
5029 }
5030}
void spawn_artifact(const tripoint &p)
Definition: map.cpp:4184
static void open()
furn_id f_wreckage
Definition: mapdata.cpp:1097
ter_id t_rock
Definition: mapdata.cpp:673
ter_id t_lava
Definition: mapdata.cpp:695
void square(map *m, const ter_id &type, const point &p1, const point &p2)
Definition: mapgen.cpp:6478
static const mongroup_id GROUP_DOG_THING("GROUP_DOG_THING")

References mapgendata::above(), abs_sub, add_field(), add_item(), mapgendata::e_fac, EAST, mapgendata::east(), EAST_EDGE, f_wreckage, fd_gas_vent, GROUP_DOG_THING, is_ot_match(), line(), item::make_corpse(), make_rubble(), move_cost(), mapgendata::n_fac, NORTH, mapgendata::north(), num, one_in(), open(), place_items(), place_spawns(), prefix, random_entry(), random_point(), rng(), mapgendata::s_fac, SEEX, SEEY, SOUTH, mapgendata::south(), SOUTH_EDGE, spawn_artifact(), square(), calendar::start_of_cataclysm, t_lava, t_rock, t_rock_floor, t_slope_down, t_slope_up, ter(), ter_set(), mapgendata::terrain_type(), mapgendata::w_fac, WEST, mapgendata::west(), point::x, point::y, and tripoint::z.

Referenced by draw_map().

◆ draw_office_tower()

void map::draw_office_tower ( mapgendata dat)
protected

Definition at line 2934 of file mapgen.cpp.

2935{
2936 const oter_id &terrain_type = dat.terrain_type();
2937 const auto place_office_chairs = [&]() {
2938 int num_chairs = rng( 0, 6 );
2939 for( int i = 0; i < num_chairs; i++ ) {
2940 add_vehicle( vproto_id( "swivel_chair" ), point( rng( 6, 16 ), rng( 6, 16 ) ),
2941 0_degrees, -1, -1, false );
2942 }
2943 };
2944
2945 const auto ter_key = mapf::ter_bind( "E > < R # X G C , _ r V H 6 x % ^ . - | "
2946 "t + = D w T S e o h c d l s", t_elevator, t_stairs_down,
2954 const auto fur_key = mapf::furn_bind( "E > < R # X G C , _ r V H 6 x % ^ . - | "
2955 "t + = D w T S e o h c d l s", f_null, f_null, f_null,
2961 f_null );
2962 const auto b_ter_key = mapf::ter_bind( "E s > < R # X G C , . r V H 6 x % ^ _ - | "
2963 "t + = D w T S e o h c d l", t_elevator, t_rock,
2971 t_floor, t_floor );
2972 const auto b_fur_key = mapf::furn_bind( "E s > < R # X G C , . r V H 6 x % ^ _ - | "
2973 "t + = D w T S e o h c d l", f_null, f_null, f_null,
2980
2981 if( terrain_type == "office_tower_1_entrance" ) {
2982 dat.fill_groundcover();
2984 "ss%|....+...|...|EEED...\n"
2985 "ss%|----|...|...|EEx|...\n"
2986 "ss%Vcdc^|...|-+-|---|...\n"
2987 "ss%Vch..+...............\n"
2988 "ss%V....|...............\n"
2989 "ss%|----|-|-+--ccc--|...\n"
2990 "ss%|..C..C|.....h..r|-+-\n"
2991 "sss=......+..h.....r|...\n"
2992 "ss%|r..CC.|.ddd....r|T.S\n"
2993 "ss%|------|---------|---\n"
2994 "ss%|####################\n"
2995 "ss%|#|------||------|###\n"
2996 "ss%|#|......||......|###\n"
2997 "ss%|||......||......|###\n"
2998 "ss%||x......||......||##\n"
2999 "ss%|||......||......x|##\n"
3000 "ss%|#|......||......||##\n"
3001 "ss%|#|......||......|###\n"
3002 "ss%|#|XXXXXX||XXXXXX|###\n"
3003 "ss%|-|__,,__||__,,__|---\n"
3004 "ss%% x_,,,,_ __,,__ %%\n"
3005 "ss __,,__ _,,,,_ \n"
3006 "ssssss__,,__ss__,,__ssss\n"
3007 "ssssss______ss______ssss\n", ter_key, fur_key );
3008 place_items( item_group_id( "office" ), 75, point( 4, 2 ), point( 6, 2 ), false,
3010 place_items( item_group_id( "office" ), 75, point( 19, 6 ), point( 19, 6 ), false,
3012 place_items( item_group_id( "office" ), 75, point( 12, 8 ), point( 14, 8 ), false,
3014 if( dat.monster_density() > 1 ) {
3016 } else {
3017 place_spawns( GROUP_PLAIN, 2, point( 15, 1 ), point( 22, 7 ), 1, true );
3018 place_spawns( GROUP_PLAIN, 2, point( 15, 1 ), point( 22, 7 ), 0.15 );
3019 place_spawns( GROUP_ZOMBIE_COP, 2, point( 10, 10 ), point( 14, 10 ), 0.1 );
3020 }
3021 place_office_chairs();
3022
3023 if( dat.north() == "office_tower_1" && dat.west() == "office_tower_1" ) {
3024 rotate( 3 );
3025 } else if( dat.north() == "office_tower_1" && dat.east() == "office_tower_1" ) {
3026 rotate( 0 );
3027 } else if( dat.south() == "office_tower_1" && dat.east() == "office_tower_1" ) {
3028 rotate( 1 );
3029 } else if( dat.west() == "office_tower_1" && dat.south() == "office_tower_1" ) {
3030 rotate( 2 );
3031 }
3032 } else if( terrain_type == "office_tower_1" ) {
3033 // Init to grass & dirt;
3034 dat.fill_groundcover();
3035 if( ( dat.south() == "office_tower_1_entrance" && dat.east() == "office_tower_1" ) ||
3036 ( dat.north() == "office_tower_1" && dat.east() == "office_tower_1_entrance" ) ||
3037 ( dat.west() == "office_tower_1" && dat.north() == "office_tower_1_entrance" ) ||
3038 ( dat.south() == "office_tower_1" && dat.west() == "office_tower_1_entrance" ) ) {
3040 " ssssssssssssssssssssssss\n"
3041 "ssssssssssssssssssssssss\n"
3042 "ss \n"
3043 "ss%%%%%%%%%%%%%%%%%%%%%%\n"
3044 "ss%|-HH-|-HH-|-HH-|HH|--\n"
3045 "ss%Vdcxl|dxdl|lddx|..|.S\n"
3046 "ss%Vdh..|dh..|..hd|..+..\n"
3047 "ss%|-..-|-..-|-..-|..|--\n"
3048 "ss%V.................|.T\n"
3049 "ss%V.................|..\n"
3050 "ss%|-..-|-..-|-..-|..|--\n"
3051 "ss%V.h..|..hd|..hd|..|..\n"
3052 "ss%Vdxdl|^dxd|.xdd|..G..\n"
3053 "ss%|----|----|----|..G..\n"
3054 "ss%|llll|..htth......|..\n"
3055 "ss%V.................|..\n"
3056 "ss%V.ddd..........|+-|..\n"
3057 "ss%|..hd|.hh.ceocc|.l|..\n"
3058 "ss%|----|---------|--|..\n"
3059 "ss%Vcdcl|...............\n"
3060 "ss%V.h..+...............\n"
3061 "ss%V...^|...|---|---|...\n"
3062 "ss%|----|...|.R>|EEE|...\n"
3063 "ss%|rrrr|...|.R.|EEED...\n", ter_key, fur_key );
3064 if( dat.monster_density() > 1 ) {
3066 } else {
3067 place_spawns( GROUP_PLAIN, 1, point( 5, 7 ), point( 15, 20 ), 0.1 );
3068 }
3069 place_items( item_group_id( "office" ), 75, point( 4, 23 ), point( 7, 23 ), false,
3071 place_items( item_group_id( "office" ), 75, point( 4, 19 ), point( 7, 19 ), false,
3073 place_items( item_group_id( "office" ), 75, point( 4, 14 ), point( 7, 14 ), false,
3075 place_items( item_group_id( "office" ), 75, point( 5, 16 ), point( 7, 16 ), false,
3077 place_items( item_group_id( "fridge" ), 80, point( 14, 17 ), point( 14, 17 ), false,
3079 place_items( item_group_id( "cleaning" ), 75, point( 19, 17 ), point( 20, 17 ), false,
3081 place_items( item_group_id( "cubical_office" ), 75, point( 6, 12 ), point( 7, 12 ), false,
3083 place_items( item_group_id( "cubical_office" ), 75, point( 12, 11 ), point( 12, 12 ), false,
3085 place_items( item_group_id( "cubical_office" ), 75, point( 16, 11 ), point( 17, 12 ), false,
3087 place_items( item_group_id( "cubical_office" ), 75, point( 4, 5 ), point( 5, 5 ), false,
3089 place_items( item_group_id( "cubical_office" ), 75, point( 11, 5 ), point( 12, 5 ), false,
3091 place_items( item_group_id( "cubical_office" ), 75, point( 14, 5 ), point( 16, 5 ), false,
3093 place_office_chairs();
3094
3095 if( dat.west() == "office_tower_1_entrance" ) {
3096 rotate( 1 );
3097 }
3098 if( dat.north() == "office_tower_1_entrance" ) {
3099 rotate( 2 );
3100 }
3101 if( dat.east() == "office_tower_1_entrance" ) {
3102 rotate( 3 );
3103 }
3104 } else if( ( dat.west() == "office_tower_1_entrance" && dat.north() == "office_tower_1" ) ||
3105 ( dat.north() == "office_tower_1_entrance" && dat.east() == "office_tower_1" ) ||
3106 ( dat.west() == "office_tower_1" && dat.south() == "office_tower_1_entrance" ) ||
3107 ( dat.south() == "office_tower_1" && dat.east() == "office_tower_1_entrance" ) ) {
3109 "...DEEE|...|..|-----|%ss\n"
3110 "...|EEE|...|..|^...lV%ss\n"
3111 "...|---|-+-|......hdV%ss\n"
3112 "...........G..|..dddV%ss\n"
3113 "...........G..|-----|%ss\n"
3114 ".......|---|..|...ddV%ss\n"
3115 "|+-|...|...+......hdV%ss\n"
3116 "|.l|...|rr.|.^|l...dV%ss\n"
3117 "|--|...|---|--|-----|%ss\n"
3118 "|...........c.......V%ss\n"
3119 "|.......cxh.c.#####.Vsss\n"
3120 "|.......ccccc.......Gsss\n"
3121 "|...................Gsss\n"
3122 "|...................Vsss\n"
3123 "|#..................Gsss\n"
3124 "|#..................Gsss\n"
3125 "|#..................Vsss\n"
3126 "|#............#####.V%ss\n"
3127 "|...................|%ss\n"
3128 "--HHHHHGGHHGGHHHHH--|%ss\n"
3129 "%%%%% ssssssss %%%%%%%ss\n"
3130 " ssssssss ss\n"
3131 "ssssssssssssssssssssssss\n"
3132 "ssssssssssssssssssssssss\n", ter_key, fur_key );
3133 place_items( item_group_id( "office" ), 75, point( 19, 1 ), point( 19, 3 ), false,
3135 place_items( item_group_id( "office" ), 75, point( 17, 3 ), point( 18, 3 ), false,
3137 place_items( item_group_id( "office" ), 90, point( 8, 7 ), point( 9, 7 ), false,
3139 place_items( item_group_id( "cubical_office" ), 75, point( 19, 5 ), point( 19, 7 ), false,
3141 place_items( item_group_id( "cleaning" ), 80, point( 1, 7 ), point( 2, 7 ), false,
3143 if( dat.monster_density() > 1 ) {
3144 place_spawns( GROUP_ZOMBIE, 2, point_zero, point( 14, 10 ), dat.monster_density() );
3145 } else {
3146 place_spawns( GROUP_PLAIN, 1, point( 10, 10 ), point( 14, 10 ), 0.15 );
3147 place_spawns( GROUP_ZOMBIE_COP, 2, point( 10, 10 ), point( 14, 10 ), 0.1 );
3148 }
3149 place_office_chairs();
3150
3151 if( dat.north() == "office_tower_1_entrance" ) {
3152 rotate( 1 );
3153 }
3154 if( dat.east() == "office_tower_1_entrance" ) {
3155 rotate( 2 );
3156 }
3157 if( dat.south() == "office_tower_1_entrance" ) {
3158 rotate( 3 );
3159 }
3160 } else {
3162 "ssssssssssssssssssssssss\n"
3163 "ssssssssssssssssssssssss\n"
3164 " ss\n"
3165 "%%%%%%%%%%%%%%%%%%%%%%ss\n"
3166 "--|---|--HHHH-HHHH--|%ss\n"
3167 ".T|..l|............^|%ss\n"
3168 "..|-+-|...hhhhhhh...V%ss\n"
3169 "--|...G...ttttttt...V%ss\n"
3170 ".S|...G...ttttttt...V%ss\n"
3171 "..+...|...hhhhhhh...V%ss\n"
3172 "--|...|.............|%ss\n"
3173 "..|...|-------------|%ss\n"
3174 "..G....|l.......dxd^|%ss\n"
3175 "..G....G...h....dh..V%ss\n"
3176 "..|....|............V%ss\n"
3177 "..|....|------|llccc|%ss\n"
3178 "..|...........|-----|%ss\n"
3179 "..|...........|...ddV%ss\n"
3180 "..|----|---|......hdV%ss\n"
3181 ".......+...|..|l...dV%ss\n"
3182 ".......|rrr|..|-----|%ss\n"
3183 "...|---|---|..|l.dddV%ss\n"
3184 "...|xEE|.R>|......hdV%ss\n"
3185 "...DEEE|.R.|..|.....V%ss\n", ter_key, fur_key );
3186 spawn_item( point( 18, 15 ), "record_accounting" );
3187 place_items( item_group_id( "cleaning" ), 75, point( 3, 5 ), point( 5, 5 ), false,
3189 place_items( item_group_id( "office" ), 75, point( 10, 7 ), point( 16, 8 ), false,
3191 place_items( item_group_id( "cubical_office" ), 75, point( 15, 15 ), point( 19, 15 ), false,
3193 place_items( item_group_id( "cubical_office" ), 75, point( 16, 12 ), point( 16, 13 ), false,
3195 place_items( item_group_id( "cubical_office" ), 75, point( 17, 19 ), point( 19, 19 ), false,
3197 place_items( item_group_id( "office" ), 75, point( 17, 21 ), point( 19, 21 ), false,
3199 place_items( item_group_id( "office" ), 75, point( 16, 11 ), point( 17, 12 ), false,
3201 place_items( item_group_id( "cleaning" ), 75, point( 8, 20 ), point( 10, 20 ), false,
3203 if( dat.monster_density() > 1 ) {
3205 } else {
3206 place_spawns( GROUP_PLAIN, 1, point_zero, point( 9, 15 ), 0.1 );
3207 }
3208 place_office_chairs();
3209
3210 if( dat.west() == "office_tower_1" && dat.north() == "office_tower_1" ) {
3211 rotate( 1 );
3212 } else if( dat.east() == "office_tower_1" && dat.north() == "office_tower_1" ) {
3213 rotate( 2 );
3214 } else if( dat.east() == "office_tower_1" && dat.south() == "office_tower_1" ) {
3215 rotate( 3 );
3216 }
3217 }
3218 } else if( terrain_type == "office_tower_b_entrance" ) {
3219 dat.fill_groundcover();
3221 "sss|........|...|EEED___\n"
3222 "sss|........|...|EEx|___\n"
3223 "sss|........|-+-|---|HHG\n"
3224 "sss|....................\n"
3225 "sss|....................\n"
3226 "sss|....................\n"
3227 "sss|....................\n"
3228 "sss|....,,......,,......\n"
3229 "sss|...,,,,.....,,......\n"
3230 "sss|....,,.....,,,,..xS.\n"
3231 "sss|....,,......,,...SS.\n"
3232 "sss|-|XXXXXX||XXXXXX|---\n"
3233 "sss|s|EEEEEE||EEEEEE|sss\n"
3234 "sss|||EEEEEE||EEEEEE|sss\n"
3235 "sss||xEEEEEE||EEEEEE||ss\n"
3236 "sss|||EEEEEE||EEEEEEx|ss\n"
3237 "sss|s|EEEEEE||EEEEEE||ss\n"
3238 "sss|s|EEEEEE||EEEEEE|sss\n"
3239 "sss|s|------||------|sss\n"
3240 "sss|--------------------\n"
3241 "ssssssssssssssssssssssss\n"
3242 "ssssssssssssssssssssssss\n"
3243 "ssssssssssssssssssssssss\n"
3244 "ssssssssssssssssssssssss\n", ter_key, fur_key );
3245 if( dat.monster_density() > 1 ) {
3247 } else {
3249 }
3250 if( dat.north() == "office_tower_b" && dat.west() == "office_tower_b" ) {
3251 rotate( 3 );
3252 } else if( dat.north() == "office_tower_b" && dat.east() == "office_tower_b" ) {
3253 rotate( 0 );
3254 } else if( dat.south() == "office_tower_b" && dat.east() == "office_tower_b" ) {
3255 rotate( 1 );
3256 } else if( dat.west() == "office_tower_b" && dat.south() == "office_tower_b" ) {
3257 rotate( 2 );
3258 }
3259 } else if( terrain_type == "office_tower_b" ) {
3260 // Init to grass & dirt;
3261 dat.fill_groundcover();
3262 if( ( dat.south() == "office_tower_b_entrance" && dat.east() == "office_tower_b" ) ||
3263 ( dat.north() == "office_tower_b" && dat.east() == "office_tower_b_entrance" ) ||
3264 ( dat.west() == "office_tower_b" && dat.north() == "office_tower_b_entrance" ) ||
3265 ( dat.south() == "office_tower_b" && dat.west() == "office_tower_b_entrance" ) ) {
3267 "ssssssssssssssssssssssss\n"
3268 "ssssssssssssssssssssssss\n"
3269 "sss|--------------------\n"
3270 "sss|,.....,.....,.....,S\n"
3271 "sss|,.....,.....,.....,S\n"
3272 "sss|,.....,.....,.....,S\n"
3273 "sss|,.....,.....,.....,S\n"
3274 "sss|,.....,.....,.....,S\n"
3275 "sss|,.....,.....,.....,S\n"
3276 "sss|....................\n"
3277 "sss|....................\n"
3278 "sss|....................\n"
3279 "sss|....................\n"
3280 "sss|....................\n"
3281 "sss|....................\n"
3282 "sss|...,,...,....,....,S\n"
3283 "sss|..,,,,..,....,....,S\n"
3284 "sss|...,,...,....,....,S\n"
3285 "sss|...,,...,....,....,S\n"
3286 "sss|........,....,....,S\n"
3287 "sss|........,....,....,S\n"
3288 "sss|........|---|---|HHG\n"
3289 "sss|........|.R<|EEE|___\n"
3290 "sss|........|.R.|EEED___\n", b_ter_key, b_fur_key );
3291 if( dat.monster_density() > 1 ) {
3293 } else {
3295 }
3296 if( dat.west() == "office_tower_b_entrance" ) {
3297 rotate( 1 );
3298 if( x_in_y( 1, 5 ) ) {
3299 add_vehicle( vproto_id( "car" ), point( 17, 7 ), 180_degrees );
3300 }
3301 if( x_in_y( 1, 3 ) ) {
3302 add_vehicle( vproto_id( "motorcycle" ), point( 17, 13 ), 180_degrees );
3303 }
3304 if( x_in_y( 1, 5 ) ) {
3305 if( one_in( 3 ) ) {
3306 add_vehicle( vproto_id( "fire_truck" ), point( 6, 13 ), 0_degrees );
3307 } else {
3308 add_vehicle( vproto_id( "pickup" ), point( 17, 19 ), 180_degrees );
3309 }
3310 }
3311 } else if( dat.north() == "office_tower_b_entrance" ) {
3312 rotate( 2 );
3313 if( x_in_y( 1, 5 ) ) {
3314 add_vehicle( vproto_id( "car" ), point( 10, 17 ), 270_degrees );
3315 }
3316 if( x_in_y( 1, 3 ) ) {
3317 add_vehicle( vproto_id( "motorcycle" ), point( 4, 18 ), 270_degrees );
3318 }
3319 if( x_in_y( 1, 5 ) ) {
3320 if( one_in( 3 ) ) {
3321 add_vehicle( vproto_id( "fire_truck" ), point( 6, 13 ), 0_degrees );
3322 } else {
3323 add_vehicle( vproto_id( "pickup" ), point( 16, 17 ), 270_degrees );
3324 }
3325 }
3326 } else if( dat.east() == "office_tower_b_entrance" ) {
3327 rotate( 3 );
3328 if( x_in_y( 1, 5 ) ) {
3329 add_vehicle( vproto_id( "car" ), point( 6, 4 ), 0_degrees );
3330 }
3331 if( x_in_y( 1, 3 ) ) {
3332 add_vehicle( vproto_id( "motorcycle" ), point( 6, 10 ), 180_degrees );
3333 }
3334 if( x_in_y( 1, 5 ) ) {
3335 add_vehicle( vproto_id( "pickup" ), point( 6, 16 ), 0_degrees );
3336 }
3337
3338 } else {
3339 if( x_in_y( 1, 5 ) ) {
3340 add_vehicle( vproto_id( "pickup" ), point( 7, 6 ), 90_degrees );
3341 }
3342 if( x_in_y( 1, 5 ) ) {
3343 add_vehicle( vproto_id( "car" ), point( 14, 6 ), 90_degrees );
3344 }
3345 if( x_in_y( 1, 3 ) ) {
3346 add_vehicle( vproto_id( "motorcycle" ), point( 19, 6 ), 90_degrees );
3347 }
3348 }
3349 } else if( ( dat.west() == "office_tower_b_entrance" && dat.north() == "office_tower_b" ) ||
3350 ( dat.north() == "office_tower_b_entrance" && dat.east() == "office_tower_b" ) ||
3351 ( dat.west() == "office_tower_b" && dat.south() == "office_tower_b_entrance" ) ||
3352 ( dat.south() == "office_tower_b" && dat.east() == "office_tower_b_entrance" ) ) {
3354 "___DEEE|...|...,,...|sss\n"
3355 "___|EEE|...|..,,,,..|sss\n"
3356 "GHH|---|-+-|...,,...|sss\n"
3357 "....................|sss\n"
3358 "....................|sss\n"
3359 "....................|sss\n"
3360 "....................|sss\n"
3361 "....................|sss\n"
3362 "....................|sss\n"
3363 "....................|sss\n"
3364 "....................|sss\n"
3365 "|...................|sss\n"
3366 "|...................|sss\n"
3367 "|,.....,.....,.....,|sss\n"
3368 "|,.....,.....,.....,|sss\n"
3369 "|,.....,.....,.....,|sss\n"
3370 "|,.....,.....,.....,|sss\n"
3371 "|,.....,.....,.....,|sss\n"
3372 "|,.....,.....,.....,|sss\n"
3373 "|-------------------|sss\n"
3374 "ssssssssssssssssssssssss\n"
3375 "ssssssssssssssssssssssss\n"
3376 "ssssssssssssssssssssssss\n"
3377 "ssssssssssssssssssssssss\n", b_ter_key, b_fur_key );
3378 if( dat.monster_density() > 1 ) {
3380 } else {
3382 }
3383 if( dat.north() == "office_tower_b_entrance" ) {
3384 rotate( 1 );
3385 if( x_in_y( 1, 5 ) ) {
3386 add_vehicle( vproto_id( "car" ), point( 8, 15 ), 0_degrees );
3387 }
3388 if( x_in_y( 1, 5 ) ) {
3389 add_vehicle( vproto_id( "pickup" ), point( 7, 10 ), 180_degrees );
3390 }
3391 if( x_in_y( 1, 3 ) ) {
3392 add_vehicle( vproto_id( "beetle" ), point( 7, 3 ), 0_degrees );
3393 }
3394 } else if( dat.east() == "office_tower_b_entrance" ) {
3395 rotate( 2 );
3396 if( x_in_y( 1, 5 ) ) {
3397 if( one_in( 3 ) ) {
3398 add_vehicle( vproto_id( "fire_truck" ), point( 6, 13 ), 0_degrees );
3399 } else {
3400 add_vehicle( vproto_id( "pickup" ), point( 7, 7 ), 270_degrees );
3401 }
3402 }
3403 if( x_in_y( 1, 5 ) ) {
3404 add_vehicle( vproto_id( "car" ), point( 13, 8 ), 90_degrees );
3405 }
3406 if( x_in_y( 1, 3 ) ) {
3407 add_vehicle( vproto_id( "beetle" ), point( 20, 7 ), 90_degrees );
3408 }
3409 } else if( dat.south() == "office_tower_b_entrance" ) {
3410 rotate( 3 );
3411 if( x_in_y( 1, 5 ) ) {
3412 add_vehicle( vproto_id( "pickup" ), point( 16, 7 ), 0_degrees );
3413 }
3414 if( x_in_y( 1, 5 ) ) {
3415 add_vehicle( vproto_id( "car" ), point( 15, 13 ), 180_degrees );
3416 }
3417 if( x_in_y( 1, 3 ) ) {
3418 add_vehicle( vproto_id( "beetle" ), point( 15, 20 ), 180_degrees );
3419 }
3420 } else {
3421 if( x_in_y( 1, 5 ) ) {
3422 add_vehicle( vproto_id( "pickup" ), point( 16, 16 ), 90_degrees );
3423 }
3424 if( x_in_y( 1, 5 ) ) {
3425 add_vehicle( vproto_id( "car" ), point( 9, 15 ), 270_degrees );
3426 }
3427 if( x_in_y( 1, 3 ) ) {
3428 add_vehicle( vproto_id( "beetle" ), point( 4, 16 ), 270_degrees );
3429 }
3430 }
3431 } else {
3433 "ssssssssssssssssssssssss\n"
3434 "ssssssssssssssssssssssss\n"
3435 "--------------------|sss\n"
3436 "S,.....,.....,.....,|sss\n"
3437 "S,.....,.....,.....,|sss\n"
3438 "S,.....,.....,.....,|sss\n"
3439 "S,.....,.....,.....,|sss\n"
3440 "S,.....,.....,.....,|sss\n"
3441 "S,.....,.....,.....,|sss\n"
3442 "....................|sss\n"
3443 "....................|sss\n"
3444 "....................|sss\n"
3445 "....................|sss\n"
3446 "....................|sss\n"
3447 "....................|sss\n"
3448 "S,....,....,........|sss\n"
3449 "S,....,....,........|sss\n"
3450 "S,....,....,........|sss\n"
3451 "S,....,....,........|sss\n"
3452 "S,....,....,........|sss\n"
3453 "S,....,....,........|sss\n"
3454 "GHH|---|---|........|sss\n"
3455 "___|xEE|.R<|........|sss\n"
3456 "___DEEE|.R.|...,,...|sss\n", b_ter_key, b_fur_key );
3457 if( dat.monster_density() > 1 ) {
3459 } else {
3461 }
3462 if( dat.west() == "office_tower_b" && dat.north() == "office_tower_b" ) {
3463 rotate( 1 );
3464 if( x_in_y( 1, 5 ) ) {
3465 if( one_in( 3 ) ) {
3466 add_vehicle( vproto_id( "cube_van" ), point( 17, 4 ), 180_degrees );
3467 } else {
3468 add_vehicle( vproto_id( "cube_van_cheap" ), point( 17, 4 ), 180_degrees );
3469 }
3470 }
3471 if( x_in_y( 1, 5 ) ) {
3472 add_vehicle( vproto_id( "pickup" ), point( 17, 10 ), 180_degrees );
3473 }
3474 if( x_in_y( 1, 3 ) ) {
3475 add_vehicle( vproto_id( "car" ), point( 17, 17 ), 180_degrees );
3476 }
3477 } else if( dat.east() == "office_tower_b" && dat.north() == "office_tower_b" ) {
3478 rotate( 2 );
3479 if( x_in_y( 1, 5 ) ) {
3480 if( one_in( 3 ) ) {
3481 add_vehicle( vproto_id( "cube_van" ), point( 6, 17 ), 270_degrees );
3482 } else {
3483 add_vehicle( vproto_id( "cube_van_cheap" ), point( 6, 17 ), 270_degrees );
3484 }
3485 }
3486 if( x_in_y( 1, 5 ) ) {
3487 add_vehicle( vproto_id( "pickup" ), point( 12, 17 ), 270_degrees );
3488 }
3489 if( x_in_y( 1, 3 ) ) {
3490 add_vehicle( vproto_id( "fire_truck" ), point( 18, 17 ), 270_degrees );
3491 }
3492 } else if( dat.east() == "office_tower_b" && dat.south() == "office_tower_b" ) {
3493 rotate( 3 );
3494 if( x_in_y( 1, 5 ) ) {
3495 add_vehicle( vproto_id( "cube_van_cheap" ), point( 6, 6 ), 0_degrees );
3496 }
3497 if( x_in_y( 1, 5 ) ) {
3498 if( one_in( 3 ) ) {
3499 add_vehicle( vproto_id( "fire_truck" ), point( 6, 13 ), 0_degrees );
3500 } else {
3501 add_vehicle( vproto_id( "pickup" ), point( 6, 13 ), 0_degrees );
3502 }
3503 }
3504 if( x_in_y( 1, 3 ) ) {
3505 add_vehicle( vproto_id( "car" ), point( 5, 19 ), 180_degrees );
3506 }
3507 } else {
3508 if( x_in_y( 1, 5 ) ) {
3509 add_vehicle( vproto_id( "flatbed_truck" ), point( 16, 6 ), 90_degrees );
3510 }
3511 if( x_in_y( 1, 5 ) ) {
3512 add_vehicle( vproto_id( "cube_van_cheap" ), point( 10, 6 ), 90_degrees );
3513 }
3514 if( x_in_y( 1, 3 ) ) {
3515 add_vehicle( vproto_id( "car" ), point( 4, 6 ), 90_degrees );
3516 }
3517 }
3518 }
3519 }
3520}
bool x_in_y(const time_duration &a, const time_duration &b)
Definition: calendar.cpp:521
void fill_groundcover()
Definition: mapgendata.cpp:125
float monster_density() const
Definition: mapgendata.h:90
furn_id f_chair
Definition: mapdata.cpp:1103
ter_id t_door_locked_alarm
Definition: mapdata.cpp:657
furn_id f_fridge
Definition: mapdata.cpp:1106
ter_id t_wall
Definition: mapdata.cpp:646
furn_id f_bookcase
Definition: mapdata.cpp:1107
ter_id t_pavement
Definition: mapdata.cpp:630
furn_id f_desk
Definition: mapdata.cpp:1103
ter_id t_railing
Definition: mapdata.cpp:688
furn_id f_indoor_plant
Definition: mapdata.cpp:1100
ter_id t_pavement_y
Definition: mapdata.cpp:630
ter_id t_wall_glass
Definition: mapdata.cpp:648
furn_id f_crate_c
Definition: mapdata.cpp:1110
furn_id f_toilet
Definition: mapdata.cpp:1101
ter_id t_window
Definition: mapdata.cpp:666
furn_id f_bench
Definition: mapdata.cpp:1104
ter_id t_door_glass_c
Definition: mapdata.cpp:664
ter_id t_console_broken
Definition: mapdata.cpp:704
ter_id t_door_locked
Definition: mapdata.cpp:657
furn_id f_locker
Definition: mapdata.cpp:1106
ter_id t_elevator
Definition: mapdata.cpp:723
furn_id f_sink
Definition: mapdata.cpp:1102
ter_id t_door_c
Definition: mapdata.cpp:656
static const mongroup_id GROUP_ZOMBIE_COP("GROUP_ZOMBIE_COP")
static const mongroup_id GROUP_PLAIN("GROUP_PLAIN")
static const mongroup_id GROUP_ZOMBIE("GROUP_ZOMBIE")
void formatted_set_simple(map *m, const point &start, const char *cstr, const format_effect< ter_id > &ter_b, const format_effect< furn_id > &furn_b)
Set terrain and furniture on the supplied map.
format_effect< furn_id > furn_bind(const char(&characters)[N], Args... ids)
Definition: mapgenformat.h:76
format_effect< ter_id > ter_bind(const char(&characters)[N], Args... ids)
The functions create a mapping of characters to ids, usable with formatted_set_simple.
Definition: mapgenformat.h:66
string_id< vehicle_prototype > vproto_id
Definition: type_id.h:193

References add_vehicle(), mapgendata::east(), EAST_EDGE, f_bench, f_bookcase, f_chair, f_counter, f_crate_c, f_desk, f_fridge, f_indoor_plant, f_locker, f_null, f_rack, f_sink, f_table, f_toilet, mapgendata::fill_groundcover(), mapf::formatted_set_simple(), mapf::furn_bind(), GROUP_PLAIN, GROUP_ZOMBIE, GROUP_ZOMBIE_COP, mapgendata::monster_density(), mapgendata::north(), one_in(), place_items(), place_spawns(), point_zero, rng(), rotate(), mapgendata::south(), SOUTH_EDGE, spawn_item(), calendar::start_of_cataclysm, t_console, t_console_broken, t_door_c, t_door_glass_c, t_door_locked, t_door_locked_alarm, t_door_metal_locked, t_elevator, t_floor, t_pavement, t_pavement_y, t_railing, t_rock, t_shrub, t_sidewalk, t_stairs_down, t_stairs_up, t_wall, t_wall_glass, t_window, mapf::ter_bind(), mapgendata::terrain_type(), mapgendata::west(), and x_in_y().

Referenced by draw_map().

◆ draw_rough_circle_furn()

void map::draw_rough_circle_furn ( const furn_id type,
const point p,
int  rad 
)

Definition at line 8430 of file map.cpp.

8431{
8432 draw_rough_circle( [this, type]( const point & q ) {
8433 this->furn_set( q, type );
8434 }, p, rad );
8435}

References draw_rough_circle(), furn_set(), and type.

Referenced by rough_circle_furn().

◆ draw_rough_circle_ter()

void map::draw_rough_circle_ter ( const ter_id type,
const point p,
int  rad 
)

Definition at line 8423 of file map.cpp.

8424{
8425 draw_rough_circle( [this, type]( const point & q ) {
8426 this->ter_set( q, type );
8427 }, p, rad );
8428}

References draw_rough_circle(), ter_set(), and type.

Referenced by rough_circle().

◆ draw_slimepit()

void map::draw_slimepit ( mapgendata dat)
protected

Definition at line 5050 of file mapgen.cpp.

5051{
5052 const oter_id &terrain_type = dat.terrain_type();
5053 if( is_ot_match( "slimepit", terrain_type, ot_match_type::prefix ) ) {
5054 for( int i = 0; i < SEEX * 2; i++ ) {
5055 for( int j = 0; j < SEEY * 2; j++ ) {
5056 if( !one_in( 10 ) && ( j < dat.n_fac * SEEX ||
5057 i < dat.w_fac * SEEX ||
5058 j > SEEY * 2 - dat.s_fac * SEEY ||
5059 i > SEEX * 2 - dat.e_fac * SEEX ) ) {
5060 ter_set( point( i, j ), ( !one_in( 10 ) ? t_slime : t_rock_floor ) );
5061 } else if( rng( 0, SEEX ) > std::abs( i - SEEX ) && rng( 0, SEEY ) > std::abs( j - SEEY ) ) {
5062 ter_set( point( i, j ), t_slime );
5063 } else if( dat.zlevel() == 0 ) {
5064 ter_set( point( i, j ), t_dirt );
5065 } else {
5066 ter_set( point( i, j ), t_rock_floor );
5067 }
5068 }
5069 }
5070 if( terrain_type == "slimepit_down" ) {
5071 ter_set( point( rng( 3, SEEX * 2 - 4 ), rng( 3, SEEY * 2 - 4 ) ), t_slope_down );
5072 }
5073 if( dat.above() == "slimepit_down" ) {
5074 switch( rng( 1, 4 ) ) {
5075 case 1:
5076 ter_set( point( rng( 0, 2 ), rng( 0, 2 ) ), t_slope_up );
5077 break;
5078 case 2:
5079 ter_set( point( rng( 0, 2 ), SEEY * 2 - rng( 1, 3 ) ), t_slope_up );
5080 break;
5081 case 3:
5082 ter_set( point( SEEX * 2 - rng( 1, 3 ), rng( 0, 2 ) ), t_slope_up );
5083 break;
5084 case 4:
5085 ter_set( point( SEEX * 2 - rng( 1, 3 ), SEEY * 2 - rng( 1, 3 ) ), t_slope_up );
5086 }
5087 }
5088 place_spawns( GROUP_BLOB, 1, point( SEEX, SEEY ), point( SEEX, SEEY ), 0.15 );
5089 place_items( item_group_id( "sewer" ), 40, point_zero, point( EAST_EDGE, SOUTH_EDGE ), true,
5091 }
5092}
static const mongroup_id GROUP_BLOB("GROUP_BLOB")

References mapgendata::above(), mapgendata::e_fac, EAST_EDGE, GROUP_BLOB, is_ot_match(), mapgendata::n_fac, one_in(), place_items(), place_spawns(), point_zero, prefix, rng(), mapgendata::s_fac, SEEX, SEEY, SOUTH_EDGE, calendar::start_of_cataclysm, t_dirt, t_rock_floor, t_slime, t_slope_down, t_slope_up, ter_set(), mapgendata::terrain_type(), mapgendata::w_fac, and mapgendata::zlevel().

Referenced by draw_map().

◆ draw_square_furn()

void map::draw_square_furn ( const furn_id type,
const point p1,
const point p2 
)

Definition at line 8400 of file map.cpp.

8401{
8402 draw_square( [this, type]( const point & p ) {
8403 this->furn_set( p, type );
8404 }, p1, p2 );
8405}
void draw_square(std::function< void(const point &)>set, point p1, point p2)

References draw_square(), furn_set(), and type.

Referenced by jmapgen_setmap::apply(), mission_start::ranch_nurse_1(), mission_start::ranch_nurse_2(), mission_start::ranch_nurse_7(), mission_start::ranch_nurse_8(), and square_furn().

◆ draw_square_ter() [1/3]

◆ draw_square_ter() [2/3]

void map::draw_square_ter ( const weighted_int_list< ter_id > &  f,
const point p1,
const point p2 
)

Definition at line 8414 of file map.cpp.

8416{
8417 draw_square( [this, f]( const point & p ) {
8418 const ter_id *tid = f.pick();
8419 this->ter_set( p, tid != nullptr ? *tid : t_null );
8420 }, p1, p2 );
8421}
ter_id t_null
Definition: mapdata.cpp:623
const T * pick(unsigned int randi) const
This will return a pointer to an object from the list randomly selected and biased by weight.
Definition: weighted_list.h:94

References draw_square(), weighted_list< W, T >::pick(), t_null, and ter_set().

◆ draw_square_ter() [3/3]

void map::draw_square_ter ( ter_id(*)()  f,
const point p1,
const point p2 
)

Definition at line 8407 of file map.cpp.

8408{
8409 draw_square( [this, f]( const point & p ) {
8410 this->ter_set( p, f() );
8411 }, p1, p2 );
8412}

References draw_square(), and ter_set().

◆ draw_temple()

void map::draw_temple ( mapgendata dat)
protected

Definition at line 4523 of file mapgen.cpp.

4524{
4525 const oter_id &terrain_type = dat.terrain_type();
4526 if( terrain_type == "temple" || terrain_type == "temple_stairs" ) {
4527 if( dat.zlevel() == 0 ) {
4528 // Ground floor
4529 // TODO: More varieties?
4530 fill_background( this, t_dirt );
4531 square( this, t_grate, point( SEEX - 1, SEEY - 1 ), point( SEEX, SEEX ) );
4532 ter_set( point( SEEX + 1, SEEY + 1 ), t_pedestal_temple );
4533 } else {
4534 // Underground! Shit's about to get interesting!
4535 // Start with all rock floor
4537 // We always start at the south and go north.
4538 // We use (y / 2 + z) % 4 to guarantee that rooms don't repeat.
4539 switch( 1 + std::abs( abs_sub.y / 2 + dat.zlevel() + 4 ) % 4 ) { // TODO: More varieties!
4540
4541 case 1:
4542 // Flame bursts
4543 square( this, t_rock, point_zero, point( SEEX - 1, SOUTH_EDGE ) );
4544 square( this, t_rock, point( SEEX + 2, 0 ), point( EAST_EDGE, SOUTH_EDGE ) );
4545 for( int i = 2; i < SEEY * 2 - 4; i++ ) {
4546 add_field( {SEEX, i, abs_sub.z}, fd_fire_vent, rng( 1, 3 ) );
4547 add_field( {SEEX + 1, i, abs_sub.z}, fd_fire_vent, rng( 1, 3 ) );
4548 }
4549 break;
4550
4551 case 2:
4552 // Spreading water
4553 square( this, t_water_dp, point( 4, 4 ), point( 5, 5 ) );
4554 // replaced mon_sewer_snake spawn with GROUP_SEWER
4555 // Decide whether a group of only sewer snakes be made, probably not worth it
4556 place_spawns( GROUP_SEWER, 1, point( 4, 4 ), point( 4, 4 ), 1, true );
4557
4558 square( this, t_water_dp, point( SEEX * 2 - 5, 4 ), point( SEEX * 2 - 4, 6 ) );
4559 place_spawns( GROUP_SEWER, 1, point( 1, SEEX * 2 - 5 ), point( 1, SEEX * 2 - 5 ), 1, true );
4560
4561 square( this, t_water_dp, point( 4, SEEY * 2 - 5 ), point( 6, SEEY * 2 - 4 ) );
4562
4563 square( this, t_water_dp, point( SEEX * 2 - 5, SEEY * 2 - 5 ), point( SEEX * 2 - 4,
4564 SEEY * 2 - 4 ) );
4565
4566 square( this, t_rock, point( 0, SEEY * 2 - 2 ), point( SEEX - 1, SOUTH_EDGE ) );
4567 square( this, t_rock, point( SEEX + 2, SEEY * 2 - 2 ), point( EAST_EDGE, SOUTH_EDGE ) );
4568 line( this, t_grate, point( SEEX, 1 ), point( SEEX + 1, 1 ) ); // To drain the water
4569 mtrap_set( this, point( SEEX, SEEY * 2 - 2 ), tr_temple_flood );
4570 mtrap_set( this, point( SEEX + 1, SEEY * 2 - 2 ), tr_temple_flood );
4571 for( int y = 2; y < SEEY * 2 - 2; y++ ) {
4572 for( int x = 2; x < SEEX * 2 - 2; x++ ) {
4573 if( ter( point( x, y ) ) == t_rock_floor && one_in( 4 ) ) {
4574 mtrap_set( this, point( x, y ), tr_temple_flood );
4575 }
4576 }
4577 }
4578 break;
4579
4580 case 3: { // Flipping walls puzzle
4581 line( this, t_rock, point_zero, point( SEEX - 1, 0 ) );
4582 line( this, t_rock, point( SEEX + 2, 0 ), point( EAST_EDGE, 0 ) );
4583 line( this, t_rock, point( SEEX - 1, 1 ), point( SEEX - 1, 6 ) );
4584 line( this, t_bars, point( SEEX + 2, 1 ), point( SEEX + 2, 6 ) );
4585 ter_set( point( 14, 1 ), t_switch_rg );
4586 ter_set( point( 15, 1 ), t_switch_gb );
4587 ter_set( point( 16, 1 ), t_switch_rb );
4588 ter_set( point( 17, 1 ), t_switch_even );
4589 // Start with clear floors--then work backwards to the starting state
4590 line( this, t_floor_red, point( SEEX, 1 ), point( SEEX + 1, 1 ) );
4591 line( this, t_floor_green, point( SEEX, 2 ), point( SEEX + 1, 2 ) );
4592 line( this, t_floor_blue, point( SEEX, 3 ), point( SEEX + 1, 3 ) );
4593 line( this, t_floor_red, point( SEEX, 4 ), point( SEEX + 1, 4 ) );
4594 line( this, t_floor_green, point( SEEX, 5 ), point( SEEX + 1, 5 ) );
4595 line( this, t_floor_blue, point( SEEX, 6 ), point( SEEX + 1, 6 ) );
4596 // Now, randomly choose actions
4597 // Set up an actions vector so that there's not undue repetition
4598 std::vector<int> actions;
4599 actions.push_back( 1 );
4600 actions.push_back( 2 );
4601 actions.push_back( 3 );
4602 actions.push_back( 4 );
4603 actions.push_back( rng( 1, 3 ) );
4604 while( !actions.empty() ) {
4605 const int action = random_entry_removed( actions );
4606 for( int y = 1; y < 7; y++ ) {
4607 for( int x = SEEX; x <= SEEX + 1; x++ ) {
4608 switch( action ) {
4609 case 1:
4610 // Toggle RG
4611 if( ter( point( x, y ) ) == t_floor_red ) {
4612 ter_set( point( x, y ), t_rock_red );
4613 } else if( ter( point( x, y ) ) == t_rock_red ) {
4614 ter_set( point( x, y ), t_floor_red );
4615 } else if( ter( point( x, y ) ) == t_floor_green ) {
4616 ter_set( point( x, y ), t_rock_green );
4617 } else if( ter( point( x, y ) ) == t_rock_green ) {
4618 ter_set( point( x, y ), t_floor_green );
4619 }
4620 break;
4621 case 2:
4622 // Toggle GB
4623 if( ter( point( x, y ) ) == t_floor_blue ) {
4624 ter_set( point( x, y ), t_rock_blue );
4625 } else if( ter( point( x, y ) ) == t_rock_blue ) {
4626 ter_set( point( x, y ), t_floor_blue );
4627 } else if( ter( point( x, y ) ) == t_floor_green ) {
4628 ter_set( point( x, y ), t_rock_green );
4629 } else if( ter( point( x, y ) ) == t_rock_green ) {
4630 ter_set( point( x, y ), t_floor_green );
4631 }
4632 break;
4633 case 3:
4634 // Toggle RB
4635 if( ter( point( x, y ) ) == t_floor_blue ) {
4636 ter_set( point( x, y ), t_rock_blue );
4637 } else if( ter( point( x, y ) ) == t_rock_blue ) {
4638 ter_set( point( x, y ), t_floor_blue );
4639 } else if( ter( point( x, y ) ) == t_floor_red ) {
4640 ter_set( point( x, y ), t_rock_red );
4641 } else if( ter( point( x, y ) ) == t_rock_red ) {
4642 ter_set( point( x, y ), t_floor_red );
4643 }
4644 break;
4645 case 4:
4646 // Toggle Even
4647 if( y % 2 == 0 ) {
4648 if( ter( point( x, y ) ) == t_floor_blue ) {
4649 ter_set( point( x, y ), t_rock_blue );
4650 } else if( ter( point( x, y ) ) == t_rock_blue ) {
4651 ter_set( point( x, y ), t_floor_blue );
4652 } else if( ter( point( x, y ) ) == t_floor_red ) {
4653 ter_set( point( x, y ), t_rock_red );
4654 } else if( ter( point( x, y ) ) == t_rock_red ) {
4655 ter_set( point( x, y ), t_floor_red );
4656 } else if( ter( point( x, y ) ) == t_floor_green ) {
4657 ter_set( point( x, y ), t_rock_green );
4658 } else if( ter( point( x, y ) ) == t_rock_green ) {
4659 ter_set( point( x, y ), t_floor_green );
4660 }
4661 }
4662 break;
4663 }
4664 }
4665 }
4666 }
4667 }
4668 break;
4669
4670 case 4: { // Toggling walls maze
4671 square( this, t_rock, point_zero, point( SEEX - 1, 1 ) );
4672 square( this, t_rock, point( 0, SEEY * 2 - 2 ), point( SEEX - 1, SOUTH_EDGE ) );
4673 square( this, t_rock, point( 0, 2 ), point( SEEX - 4, SEEY * 2 - 3 ) );
4674 square( this, t_rock, point( SEEX + 2, 0 ), point( EAST_EDGE, 1 ) );
4675 square( this, t_rock, point( SEEX + 2, SEEY * 2 - 2 ), point( EAST_EDGE, SOUTH_EDGE ) );
4676 square( this, t_rock, point( SEEX + 5, 2 ), point( EAST_EDGE, SEEY * 2 - 3 ) );
4677 int x = rng( SEEX - 1, SEEX + 2 ), y = 2;
4678 std::vector<point> path; // Path, from end to start
4679 while( x < SEEX - 1 || x > SEEX + 2 || y < SEEY * 2 - 2 ) {
4680 static const std::vector<ter_id> terrains = {
4682 };
4683 path.push_back( point( x, y ) );
4684 ter_set( point( x, y ), random_entry( terrains ) );
4685 if( y == SEEY * 2 - 2 ) {
4686 if( x < SEEX - 1 ) {
4687 x++;
4688 } else if( x > SEEX + 2 ) {
4689 x--;
4690 }
4691 } else {
4692 std::vector<point> next;
4693 for( int nx = x - 1; nx <= x + 1; nx++ ) {
4694 for( int ny = y; ny <= y + 1; ny++ ) {
4695 if( ter( point( nx, ny ) ) == t_rock_floor ) {
4696 next.push_back( point( nx, ny ) );
4697 }
4698 }
4699 }
4700 if( next.empty() ) {
4701 break;
4702 } else {
4703 const point p = random_entry( next );
4704 x = p.x;
4705 y = p.y;
4706 }
4707 }
4708 }
4709 // Now go backwards through path (start to finish), toggling any tiles that need
4710 bool toggle_red = false;
4711 bool toggle_green = false;
4712 bool toggle_blue = false;
4713 for( int i = path.size() - 1; i >= 0; i-- ) {
4714 if( ter( path[i] ) == t_floor_red ) {
4715 toggle_green = !toggle_green;
4716 if( toggle_red ) {
4717 ter_set( path[i], t_rock_red );
4718 }
4719 } else if( ter( path[i] ) == t_floor_green ) {
4720 toggle_blue = !toggle_blue;
4721 if( toggle_green ) {
4722 ter_set( path[i], t_rock_green );
4723 }
4724 } else if( ter( path[i] ) == t_floor_blue ) {
4725 toggle_red = !toggle_red;
4726 if( toggle_blue ) {
4727 ter_set( path[i], t_rock_blue );
4728 }
4729 }
4730 }
4731 // Finally, fill in the rest with random tiles, and place toggle traps
4732 for( int i = SEEX - 3; i <= SEEX + 4; i++ ) {
4733 for( int j = 2; j <= SEEY * 2 - 2; j++ ) {
4734 mtrap_set( this, point( i, j ), tr_temple_toggle );
4735 if( ter( point( i, j ) ) == t_rock_floor ) {
4736 static const std::vector<ter_id> terrains = {
4739 };
4740 ter_set( point( i, j ), random_entry( terrains ) );
4741 }
4742 }
4743 }
4744 }
4745 break;
4746 } // Done with room type switch
4747 // Stairs down if we need them
4748 if( terrain_type == "temple_stairs" ) {
4749 line( this, t_stairs_down, point( SEEX, 0 ), point( SEEX + 1, 0 ) );
4750 }
4751 // Stairs at the south if dat.above() has stairs down.
4752 if( dat.above() == "temple_stairs" ) {
4753 line( this, t_stairs_up, point( SEEX, SOUTH_EDGE ), point( SEEX + 1, SOUTH_EDGE ) );
4754 }
4755
4756 } // Done with underground-only stuff
4757 } else if( terrain_type == "temple_finale" ) {
4758 fill_background( this, t_rock );
4759 square( this, t_rock_floor, point( SEEX - 1, 1 ), point( SEEX + 2, 4 ) );
4760 square( this, t_rock_floor, point( SEEX, 5 ), point( SEEX + 1, SOUTH_EDGE ) );
4761 line( this, t_stairs_up, point( SEEX, SOUTH_EDGE ), point( SEEX + 1, SOUTH_EDGE ) );
4762 spawn_artifact( tripoint( rng( SEEX, SEEX + 1 ), rng( 2, 3 ), abs_sub.z ) );
4763 spawn_artifact( tripoint( rng( SEEX, SEEX + 1 ), rng( 2, 3 ), abs_sub.z ) );
4764 return;
4765
4766 }
4767}
@ action
Definition: dialogue.h:36
ter_id t_switch_even
Definition: mapdata.cpp:727
ter_id t_rock_red
Definition: mapdata.cpp:726
ter_id t_pedestal_temple
Definition: mapdata.cpp:724
ter_id t_floor_blue
Definition: mapdata.cpp:726
ter_id t_grate
Definition: mapdata.cpp:636
ter_id t_switch_rb
Definition: mapdata.cpp:727
ter_id t_rock_green
Definition: mapdata.cpp:726
ter_id t_rock_blue
Definition: mapdata.cpp:726
ter_id t_floor_green
Definition: mapdata.cpp:726
ter_id t_switch_gb
Definition: mapdata.cpp:727
ter_id t_floor_red
Definition: mapdata.cpp:726
ter_id t_switch_rg
Definition: mapdata.cpp:727
static const mongroup_id GROUP_SEWER("GROUP_SEWER")
static const trap_str_id tr_temple_flood("tr_temple_flood")
generic_factory< oter_t > terrains("overmap terrain")
V random_entry_removed(C &container)
Returns a random entry in the container and removes it from the container.
Definition: rng.h:170
trap_id tr_temple_toggle
Definition: trap.cpp:311

References mapgendata::above(), abs_sub, action, add_field(), EAST_EDGE, fd_fire_vent, fill_background(), GROUP_SEWER, line(), mtrap_set(), one_in(), place_spawns(), point_zero, random_entry(), random_entry_removed(), rng(), SEEX, SEEY, SOUTH_EDGE, spawn_artifact(), square(), t_bars, t_dirt, t_floor_blue, t_floor_green, t_floor_red, t_grate, t_pedestal_temple, t_rock, t_rock_blue, t_rock_floor, t_rock_green, t_rock_red, t_stairs_down, t_stairs_up, t_switch_even, t_switch_gb, t_switch_rb, t_switch_rg, t_water_dp, ter(), ter_set(), mapgendata::terrain_type(), anonymous_namespace{overmap.cpp}::terrains, tr_temple_flood, tr_temple_toggle, point::x, point::y, tripoint::y, tripoint::z, and mapgendata::zlevel().

Referenced by draw_map().

◆ draw_triffid()

void map::draw_triffid ( mapgendata dat)
protected

Definition at line 5094 of file mapgen.cpp.

5095{
5096 const oter_id &terrain_type = dat.terrain_type();
5097 if( terrain_type == "triffid_roots" ) {
5099 int node = 0;
5100 int step = 0;
5101 bool node_built[16];
5102 bool done = false;
5103 for( auto &elem : node_built ) {
5104 elem = false;
5105 }
5106 do {
5107 node_built[node] = true;
5108 step++;
5109 point node2( 1 + 6 * ( node % 4 ), 1 + 6 * static_cast<int>( node / 4 ) );
5110 // Clear a 4x4 dirt square
5111 square( this, t_dirt, node2, node2 + point( 3, 3 ) );
5112 // Spawn a monster in there
5113 if( step > 2 ) { // First couple of chambers are safe
5114 int monrng = rng( 1, 25 );
5115 point spawn( node2 + point{ rng( 0, 3 ), rng( 0, 3 ) } );
5116 if( monrng <= 24 ) {
5118 node2 + point( 3, 3 ), 1, true );
5119 } else {
5120 for( int webx = node2.x; webx <= node2.x + 3; webx++ ) {
5121 for( int weby = node2.y; weby <= node2.y + 3; weby++ ) {
5122 add_field( {webx, weby, abs_sub.z}, fd_web, rng( 1, 3 ) );
5123 }
5124 }
5125 place_spawns( GROUP_SPIDER, 1, spawn, spawn, 1, true );
5126 }
5127 }
5128 // TODO: Non-monster hazards?
5129 // Next, pick a cell to move to
5130 std::vector<direction> move;
5131 if( node % 4 > 0 && !node_built[node - 1] ) {
5132 move.push_back( direction::WEST );
5133 }
5134 if( node % 4 < 3 && !node_built[node + 1] ) {
5135 move.push_back( direction::EAST );
5136 }
5137 if( static_cast<int>( node / 4 ) > 0 && !node_built[node - 4] ) {
5138 move.push_back( direction::NORTH );
5139 }
5140 if( static_cast<int>( node / 4 ) < 3 && !node_built[node + 4] ) {
5141 move.push_back( direction::SOUTH );
5142 }
5143
5144 if( move.empty() ) { // Nowhere to go!
5145 square( this, t_slope_down, node2 + point_south_east, node2 + point( 2, 2 ) );
5146 done = true;
5147 } else {
5148 switch( random_entry( move ) ) {
5149 case direction::NORTH:
5150 square( this, t_dirt, node2 + point( 1, -2 ), node2 + point( 2, -1 ) );
5151 node -= 4;
5152 break;
5153 case direction::EAST:
5154 square( this, t_dirt, node2 + point( 4, 1 ), node2 + point( 5, 2 ) );
5155 node++;
5156 break;
5157 case direction::SOUTH:
5158 square( this, t_dirt, node2 + point( 1, 4 ), node2 + point( 2, 5 ) );
5159 node += 4;
5160 break;
5161 case direction::WEST:
5162 square( this, t_dirt, node2 + point( -2, 1 ), node2 + point( -1, 2 ) );
5163 node--;
5164 break;
5165 default:
5166 break;
5167 }
5168 }
5169 } while( !done );
5170 square( this, t_slope_up, point( 2, 2 ), point( 3, 3 ) );
5171 rotate( rng( 0, 3 ) );
5172 } else if( terrain_type == "triffid_finale" ) {
5174 // NOLINTNEXTLINE(cata-use-named-point-constants)
5175 square( this, t_dirt, point( 1, 1 ), point( 4, 4 ) );
5176 square( this, t_dirt, point( 19, 19 ), point( 22, 22 ) );
5177 // Drunken walk until we reach the heart (lower right, [19, 19])
5178 // Chance increases by 1 each turn, and gives the % chance of forcing a move
5179 // to the right or down.
5180 int chance = 0;
5181 int x = 4;
5182 int y = 4;
5183 do {
5184 ter_set( point( x, y ), t_dirt );
5185
5186 if( chance >= 10 && one_in( 10 ) ) { // Add a spawn
5187 place_spawns( GROUP_TRIFFID, 1, point( x, y ), point( x, y ), 1, true );
5188 }
5189
5190 if( rng( 0, 99 ) < chance ) { // Force movement down or to the right
5191 if( x >= 19 ) {
5192 y++;
5193 } else if( y >= 19 ) {
5194 x++;
5195 } else {
5196 if( one_in( 2 ) ) {
5197 x++;
5198 } else {
5199 y++;
5200 }
5201 }
5202 } else {
5203 chance++; // Increase chance of forced movement down/right
5204 // Weigh movement towards directions with lots of existing walls
5205 int chance_west = 0;
5206 int chance_east = 0;
5207 int chance_north = 0;
5208 int chance_south = 0;
5209 for( int dist = 1; dist <= 5; dist++ ) {
5210 if( ter( point( x - dist, y ) ) == t_root_wall ) {
5211 chance_west++;
5212 }
5213 if( ter( point( x + dist, y ) ) == t_root_wall ) {
5214 chance_east++;
5215 }
5216 if( ter( point( x, y - dist ) ) == t_root_wall ) {
5217 chance_north++;
5218 }
5219 if( ter( point( x, y + dist ) ) == t_root_wall ) {
5220 chance_south++;
5221 }
5222 }
5223 int roll = rng( 0, chance_west + chance_east + chance_north + chance_south );
5224 if( roll < chance_west && x > 0 ) {
5225 x--;
5226 } else if( roll < chance_west + chance_east && x < EAST_EDGE ) {
5227 x++;
5228 } else if( roll < chance_west + chance_east + chance_north && y > 0 ) {
5229 y--;
5230 } else if( y < SOUTH_EDGE ) {
5231 y++;
5232 }
5233 } // Done with drunken walk
5234 } while( x < 19 || y < 19 );
5235 // NOLINTNEXTLINE(cata-use-named-point-constants)
5236 square( this, t_slope_up, point( 1, 1 ), point( 2, 2 ) );
5237 place_spawns( GROUP_TRIFFID_HEART, 1, point( 21, 21 ), point( 21, 21 ), 1, true );
5238
5239 }
5240}
ter_id t_root_wall
Definition: mapdata.cpp:684
static const mongroup_id GROUP_TRIFFID_OUTER("GROUP_TRIFFID_OUTER")
static const mongroup_id GROUP_SPIDER("GROUP_SPIDER")
static const mongroup_id GROUP_TRIFFID("GROUP_TRIFFID")
static const mongroup_id GROUP_TRIFFID_HEART("GROUP_TRIFFID_HEART")

References abs_sub, add_field(), detail::digits::done, EAST, EAST_EDGE, fd_web, fill_background(), GROUP_SPIDER, GROUP_TRIFFID, GROUP_TRIFFID_HEART, GROUP_TRIFFID_OUTER, avatar_action::move(), NORTH, one_in(), place_spawns(), point_south_east, random_entry(), rng(), rotate(), SOUTH, SOUTH_EDGE, square(), t_dirt, t_root_wall, t_slope_down, t_slope_up, ter(), ter_set(), mapgendata::terrain_type(), WEST, point::x, point::y, and tripoint::z.

Referenced by draw_map().

◆ drawsq()

void map::drawsq ( const catacurses::window w,
const tripoint p,
const drawsq_params params 
) const

Draw the map tile at the given coordinate.

Called by map::draw().

Parameters
wThe window we are drawing in
pThe tile on this map to draw.
paramsDraw parameters.

Definition at line 5840 of file map.cpp.

5842{
5843 // If we are in tiles mode, the only thing we want to potentially draw is a highlight
5844 if( is_draw_tiles_mode() ) {
5845 if( params.highlight() ) {
5846 g->draw_highlight( p );
5847 }
5848 return;
5849 }
5850
5851 if( !inbounds( p ) ) {
5852 return;
5853 }
5854
5855 const tripoint view_center = params.center();
5856 const int k = p.x + getmaxx( w ) / 2 - view_center.x;
5857 const int j = p.y + getmaxy( w ) / 2 - view_center.y;
5858 wmove( w, point( k, j ) );
5859
5860 const maptile tile = maptile_at( p );
5861 if( draw_maptile( w, p, tile, params ) ) {
5862 return;
5863 }
5864
5865 tripoint below( p.xy(), p.z - 1 );
5866 const maptile tile_below = maptile_at( below );
5867 draw_from_above( w, below, tile_below, params );
5868}
maptile maptile_at(const tripoint &p) const
Definition: map.cpp:201
constexpr drawsq_params & center(const tripoint &p)
Set view center.
Definition: map.h:283

References drawsq_params::center(), draw_from_above(), draw_maptile(), g, catacurses::getmaxx(), catacurses::getmaxy(), drawsq_params::highlight(), inbounds(), is_draw_tiles_mode(), maptile_at(), catacurses::wmove(), tripoint::x, tripoint::xy(), tripoint::y, and tripoint::z.

Referenced by choose_adjacent_highlight(), anonymous_namespace{animation.cpp}::draw_line_curses(), game::draw_look_around_cursor(), editmap::draw_main_ui_overlay(), target_ui::draw_terrain_overlay(), game::pickup(), place_construction(), and editmap::uber_draw_ter().

◆ drop_everything()

void map::drop_everything ( const tripoint p)

Handles map objects of given type (not creatures) falling down.

Returns true if anything changed.

Definition at line 2045 of file map.cpp.

2046{
2047 //Do a suspension check so that there won't be a floor there for the rest of this check.
2048 if( has_flag( "SUSPENDED", p ) ) {
2050 }
2051 if( has_floor( p ) ) {
2052 return;
2053 }
2054
2055 drop_furniture( p );
2056 drop_items( p );
2057 drop_vehicle( p );
2058 drop_fields( p );
2059}
void drop_furniture(const tripoint &p)
Definition: map.cpp:2061
void drop_items(const tripoint &p)
Definition: map.cpp:2203
void drop_vehicle(const tripoint &p)
Definition: map.cpp:2233
void collapse_invalid_suspension(const tripoint &point)
Triggers a recursive collapse of suspended tiles based on their support validity.
Definition: map.cpp:2963
void drop_fields(const tripoint &p)
Definition: map.cpp:2243
bool has_floor(const tripoint &p) const
Definition: map.cpp:2007

References collapse_invalid_suspension(), drop_fields(), drop_furniture(), drop_items(), drop_vehicle(), has_flag(), and has_floor().

Referenced by process_falling().

◆ drop_fields()

void map::drop_fields ( const tripoint p)

Definition at line 2243 of file map.cpp.

2244{
2245 field &fld = field_at( p );
2246 if( fld.field_count() == 0 ) {
2247 return;
2248 }
2249
2250 std::list<field_type_id> dropped;
2251 const tripoint below = p + tripoint_below;
2252 for( const auto &iter : fld ) {
2253 const field_entry &entry = iter.second;
2254 // For now only drop cosmetic fields, which don't warrant per-turn check
2255 // Active fields "drop themselves"
2256 if( entry.decays_on_actualize() ) {
2257 add_field( below, entry.get_field_type(), entry.get_field_intensity(), entry.get_field_age() );
2258 dropped.push_back( entry.get_field_type() );
2259 }
2260 }
2261
2262 for( const auto &entry : dropped ) {
2263 fld.remove_field( entry );
2264 }
2265}
bool decays_on_actualize() const
Definition: field.h:105

References add_field(), field_entry::decays_on_actualize(), field_at(), field::field_count(), field_entry::get_field_age(), field_entry::get_field_intensity(), field_entry::get_field_type(), field::remove_field(), and tripoint_below.

Referenced by drop_everything().

◆ drop_furniture()

void map::drop_furniture ( const tripoint p)

Definition at line 2061 of file map.cpp.

2062{
2063 const furn_id frn = furn( p );
2064 if( frn == f_null ) {
2065 return;
2066 }
2067
2068 enum support_state {
2069 SS_NO_SUPPORT = 0,
2070 SS_BAD_SUPPORT, // TODO: Implement bad, shaky support
2071 SS_GOOD_SUPPORT,
2072 SS_FLOOR, // Like good support, but bash floor instead of tile below
2073 SS_CREATURE
2074 };
2075
2076 // Checks if the tile:
2077 // has floor (supports unconditionally)
2078 // has support below
2079 // has unsupporting furniture below (bad support, things should "slide" if possible)
2080 // has no support and thus allows things to fall through
2081 const auto check_tile = [this]( const tripoint & pt ) {
2082 if( has_floor( pt ) ) {
2083 return SS_FLOOR;
2084 }
2085
2086 tripoint below_dest( pt.xy(), pt.z - 1 );
2087 if( supports_above( below_dest ) ) {
2088 return SS_GOOD_SUPPORT;
2089 }
2090
2091 const furn_id frn_id = furn( below_dest );
2092 if( frn_id != f_null ) {
2093 const furn_t &frn = frn_id.obj();
2094 // Allow crushing tiny/nocollide furniture
2095 if( !frn.has_flag( "TINY" ) && !frn.has_flag( "NOCOLLIDE" ) ) {
2096 return SS_BAD_SUPPORT;
2097 }
2098 }
2099
2100 if( g->critter_at( below_dest ) != nullptr ) {
2101 // Smash a critter
2102 return SS_CREATURE;
2103 }
2104
2105 return SS_NO_SUPPORT;
2106 };
2107
2108 tripoint current( p.xy(), p.z + 1 );
2109 support_state last_state = SS_NO_SUPPORT;
2110 while( last_state == SS_NO_SUPPORT ) {
2111 current.z--;
2112 // Check current tile
2113 last_state = check_tile( current );
2114 }
2115
2116 if( current == p ) {
2117 // Nothing happened
2118 if( last_state != SS_FLOOR ) {
2119 support_dirty( current );
2120 }
2121
2122 return;
2123 }
2124
2125 furn_set( p, f_null );
2126 furn_set( current, frn );
2127
2128 // If it's sealed, we need to drop items with it
2129 const auto &frn_obj = frn.obj();
2130 if( frn_obj.has_flag( TFLAG_SEALED ) && has_items( p ) ) {
2131 auto old_items = i_at( p );
2132 auto new_items = i_at( current );
2133 for( const auto &it : old_items ) {
2134 new_items.insert( it );
2135 }
2136
2137 i_clear( p );
2138 }
2139
2140 // Approximate weight/"bulkiness" based on strength to drag
2141 int weight;
2142 if( frn_obj.has_flag( "TINY" ) || frn_obj.has_flag( "NOCOLLIDE" ) ) {
2143 weight = 5;
2144 } else {
2145 weight = frn_obj.is_movable() ? frn_obj.move_str_req : 20;
2146 }
2147
2148 if( frn_obj.has_flag( "ROUGH" ) || frn_obj.has_flag( "SHARP" ) ) {
2149 weight += 5;
2150 }
2151
2152 // TODO: Balance this.
2153 int dmg = weight * ( p.z - current.z );
2154
2155 if( last_state == SS_FLOOR ) {
2156 // Bash the same tile twice - once for furniture, once for the floor
2157 bash( current, dmg, false, false, true );
2158 bash( current, dmg, false, false, true );
2159 } else if( last_state == SS_BAD_SUPPORT || last_state == SS_GOOD_SUPPORT ) {
2160 bash( current, dmg, false, false, false );
2161 tripoint below( current.xy(), current.z - 1 );
2162 bash( below, dmg, false, false, false );
2163 } else if( last_state == SS_CREATURE ) {
2164 const std::string &furn_name = frn_obj.name();
2165 bash( current, dmg, false, false, false );
2166 tripoint below( current.xy(), current.z - 1 );
2167 Creature *critter = g->critter_at( below );
2168 if( critter == nullptr ) {
2169 debugmsg( "drop_furniture couldn't find creature at %d,%d,%d",
2170 below.x, below.y, below.z );
2171 return;
2172 }
2173
2174 critter->add_msg_player_or_npc( m_bad, _( "Falling %s hits you!" ),
2175 _( "Falling %s hits <npcname>" ),
2176 furn_name );
2177 // TODO: A chance to dodge/uncanny dodge
2178 player *pl = dynamic_cast<player *>( critter );
2179 monster *mon = dynamic_cast<monster *>( critter );
2180 if( pl != nullptr ) {
2181 pl->deal_damage( nullptr, bodypart_id( "torso" ), damage_instance( DT_BASH, rng( dmg / 3, dmg ), 0,
2182 0.5f ) );
2183 pl->deal_damage( nullptr, bodypart_id( "head" ), damage_instance( DT_BASH, rng( dmg / 3, dmg ), 0,
2184 0.5f ) );
2185 pl->deal_damage( nullptr, bodypart_id( "leg_l" ), damage_instance( DT_BASH, rng( dmg / 2, dmg ), 0,
2186 0.4f ) );
2187 pl->deal_damage( nullptr, bodypart_id( "leg_r" ), damage_instance( DT_BASH, rng( dmg / 2, dmg ), 0,
2188 0.4f ) );
2189 pl->deal_damage( nullptr, bodypart_id( "arm_l" ), damage_instance( DT_BASH, rng( dmg / 2, dmg ), 0,
2190 0.4f ) );
2191 pl->deal_damage( nullptr, bodypart_id( "arm_r" ), damage_instance( DT_BASH, rng( dmg / 2, dmg ), 0,
2192 0.4f ) );
2193 } else if( mon != nullptr ) {
2194 // TODO: Monster's armor and size - don't crush hulks with chairs
2195 mon->apply_damage( nullptr, bodypart_id( "torso" ), rng( dmg, dmg * 2 ) );
2196 }
2197 }
2198
2199 // Re-queue for another check, in case bash destroyed something
2200 support_dirty( current );
2201}
bool supports_above(const tripoint &p) const
Does this tile support vehicles and furniture above it.
Definition: map.cpp:2020
void apply_damage(Creature *source, bodypart_id bp, int dam, bool bypass_med=false) override
Definition: monster.cpp:1660

References _, Creature::add_msg_player_or_npc(), monster::apply_damage(), bash(), Character::deal_damage(), debugmsg, DT_BASH, f_null, furn(), furn_set(), g, map_data_common_t::has_flag(), has_floor(), has_items(), i_at(), i_clear(), m_bad, int_id< T >::obj(), rng(), support_dirty(), supports_above(), TFLAG_SEALED, tripoint::x, tripoint::xy(), tripoint::y, and tripoint::z.

Referenced by drop_everything().

◆ drop_items()

void map::drop_items ( const tripoint p)

Definition at line 2203 of file map.cpp.

2204{
2205 if( !has_items( p ) ) {
2206 return;
2207 }
2208
2209 auto items = i_at( p );
2210 // TODO: Make items check the volume tile below can accept
2211 // rather than disappearing if it would be overloaded
2212
2213 tripoint below( p );
2214 while( !has_floor( below ) ) {
2215 below.z--;
2216 }
2217
2218 if( below == p ) {
2219 return;
2220 }
2221
2222 for( const auto &i : items ) {
2223 // TODO: Bash the item up before adding it
2224 // TODO: Bash the creature, terrain, furniture and vehicles on the tile
2225 add_item_or_charges( below, i );
2226 }
2227
2228 // Just to make a sound for now
2229 bash( below, 1 );
2230 i_clear( p );
2231}

References add_item_or_charges(), bash(), has_floor(), has_items(), i_at(), i_clear(), and tripoint::z.

Referenced by drop_everything().

◆ drop_vehicle()

void map::drop_vehicle ( const tripoint p)

Definition at line 2233 of file map.cpp.

2234{
2235 const optional_vpart_position vp = veh_at( p );
2236 if( !vp ) {
2237 return;
2238 }
2239
2240 vp->vehicle().is_falling = true;
2241}

References veh_at().

Referenced by drop_everything().

◆ emit_field()

void map::emit_field ( const tripoint pos,
const emit_id src,
float  mul = 1.0f 
)

Runs one cycle of emission src which may result in propagation of fields.

Parameters
posLocation of emission
srcId of object producing the emission
mulMultiplies the chance and possibly qty (if chance*mul > 100) of the emission

Definition at line 1928 of file map_field.cpp.

1929{
1930 if( !src.is_valid() ) {
1931 return;
1932 }
1933
1934 const float chance = src->chance() * mul;
1935 if( src.is_valid() && x_in_y( chance, 100 ) ) {
1936 const int qty = chance > 100.0f ? roll_remainder( src->qty() * chance / 100.0f ) : src->qty();
1937 propagate_field( pos, src->field(), qty, src->intensity() );
1938 }
1939}
int intensity() const
Intensity of output fields, range [1..maximum_intensity].
Definition: emit.h:34
int qty() const
Units of field to generate per turn subject to chance.
Definition: emit.h:39
int chance() const
Chance to emit each turn, range [1..100].
Definition: emit.h:44
field_type_id field() const
Type of field to emit.
Definition: emit.h:29
void propagate_field(const tripoint &center, const field_type_id &type, int amount, int max_intensity=0)
Definition: map_field.cpp:1941
bool is_valid() const
Returns whether this id is valid, that means whether it refers to an existing object.
Definition: achievement.cpp:65
int roll_remainder(double value)
Definition: rng.cpp:96

References emit::chance(), emit::field(), emit::intensity(), string_id< T >::is_valid(), propagate_field(), emit::qty(), roll_remainder(), and x_in_y().

Referenced by enchantment::activate_passive(), Character::burn_fuel(), game::do_turn(), Character::heat_emission(), Character::passive_power_gen(), item::process_internal(), projectile_attack(), and emit_actor::use().

◆ examine()

void map::examine ( Character p,
const tripoint pos 
)

Calls the examine function of furniture or terrain at given tile, for given character.

Examines the tile pos, with character as the "examinator" Casts Character to player because player/NPC split isn't done yet.

Will only examine terrain if furniture had iexamine::none as the examine function.

Definition at line 1620 of file map.cpp.

1621{
1622 const auto furn_here = furn( pos ).obj();
1623 if( furn_here.examine != iexamine::none ) {
1624 furn_here.examine( dynamic_cast<player &>( p ), pos );
1625 } else {
1626 ter( pos ).obj().examine( dynamic_cast<player &>( p ), pos );
1627 }
1628}
void none(player &p, const tripoint &examp)
Nothing player can interact with here.
Definition: iexamine.cpp:249
iexamine_function examine
Definition: mapdata.h:398

References map_data_common_t::examine, furn(), iexamine::none(), int_id< T >::obj(), wrapped_vehicle::pos, and ter().

Referenced by npc::pick_up_item(), and water_from().

◆ features() [1/2]

std::string map::features ( const point p)
inline

Definition at line 959 of file map.h.

959 {
960 return features( tripoint( p, abs_sub.z ) );
961 }
std::string features(const tripoint &p)
Definition: map.cpp:1714

References abs_sub, features(), and tripoint::z.

◆ features() [2/2]

std::string map::features ( const tripoint p)

Definition at line 1714 of file map.cpp.

1715{
1716 std::string result;
1717 const auto add = [&]( const std::string & text ) {
1718 if( !result.empty() ) {
1719 result += " ";
1720 }
1721 result += text;
1722 };
1723 const auto add_if = [&]( const bool cond, const std::string & text ) {
1724 if( cond ) {
1725 add( text );
1726 }
1727 };
1728 // This is used in an info window that is 46 characters wide, and is expected
1729 // to take up one line. So, make sure it does that.
1730 // FIXME: can't control length of localized text.
1731 add_if( is_bashable( p ), _( "Smashable." ) );
1732 add_if( has_flag( "DIGGABLE", p ), _( "Diggable." ) );
1733 add_if( has_flag( "PLOWABLE", p ), _( "Plowable." ) );
1734 add_if( has_flag( "ROUGH", p ), _( "Rough." ) );
1735 add_if( has_flag( "UNSTABLE", p ), _( "Unstable." ) );
1736 add_if( has_flag( "SHARP", p ), _( "Sharp." ) );
1737 add_if( has_flag( "FLAT", p ), _( "Flat." ) );
1738 add_if( has_flag( "EASY_DECONSTRUCT", p ), _( "Simple." ) );
1739 add_if( has_flag( "MOUNTABLE", p ), _( "Mountable." ) );
1740 return result;
1741}
bool is_bashable(const tripoint &p, bool allow_floor=false) const
Returns true if there is a bashable vehicle part or the furn/terrain is bashable at p.
Definition: map.cpp:2425
type add(type dir1, type dir2)
Returns a sum of two numbers.
Definition: overmap.cpp:4192

References _, om_direction::add(), has_flag(), and is_bashable().

Referenced by features(), game::print_terrain_info(), and editmap::update_view_with_help().

◆ field_at() [1/2]

field & map::field_at ( const tripoint p)

Gets fields that are here.

Both for querying and edition.

Definition at line 5315 of file map.cpp.

5316{
5317 if( !inbounds( p ) ) {
5318 nulfield = field();
5319 return nulfield;
5320 }
5321
5322 point l;
5323 submap *const current_submap = get_submap_at( p, l );
5324
5325 return current_submap->get_field( l );
5326}
static field nulfield
Definition: map.cpp:141

References submap::get_field(), get_submap_at(), inbounds(), and nulfield.

◆ field_at() [2/2]

const field & map::field_at ( const tripoint p) const

Get the fields that are here.

This is for querying and looking at it only, one can not change the fields.

Parameters
pThe local map coordinates, if out of bounds, returns an empty field.

Definition at line 5299 of file map.cpp.

5300{
5301 if( !inbounds( p ) ) {
5302 nulfield = field();
5303 return nulfield;
5304 }
5305
5306 point l;
5307 submap *const current_submap = get_submap_at( p, l );
5308
5309 return current_submap->get_field( l );
5310}

References submap::get_field(), get_submap_at(), inbounds(), and nulfield.

Referenced by Character::adjacent_tile(), npc::could_move_onto(), dangerous_field_at(), decay_cosmetic_fields(), editmap_hilight::draw(), editmap::draw_main_ui_overlay(), drop_fields(), get_convection_temperature(), game::get_dangerous_tile(), get_field(), get_field_age(), get_field_intensity(), npc::good_escape_direction(), advanced_inv_area::init(), mop_spills(), game::print_fields_info(), process_fields_in_submap(), smash(), spell_move(), and Character::symbol_color().

◆ fill_funnels()

void map::fill_funnels ( const tripoint p,
const time_point since 
)
protected

Try to fill funnel based items here.

Simulates rain from since till now.

Parameters
pThe location in this map where to fill funnels.

Definition at line 7141 of file map.cpp.

7142{
7143 const auto &tr = tr_at( p );
7144 if( !tr.is_funnel() ) {
7145 return;
7146 }
7147 // Note: the inside/outside cache might not be correct at this time
7149 return;
7150 }
7151 auto items = i_at( p );
7152 units::volume maxvolume = 0_ml;
7153 auto biggest_container = items.end();
7154 for( auto candidate = items.begin(); candidate != items.end(); ++candidate ) {
7155 if( candidate->is_funnel_container( maxvolume ) ) {
7156 biggest_container = candidate;
7157 }
7158 }
7159 if( biggest_container != items.end() ) {
7160 retroactively_fill_from_funnel( *biggest_container, tr, since, calendar::turn, getabs( p ) );
7161 }
7162}
void retroactively_fill_from_funnel(item &it, const trap &tr, const time_point &start, const time_point &end, const tripoint &pos)
Determine what a funnel has filled out of game, using funnelcontainer.bday as a starting point.
Definition: weather.cpp:184

References getabs(), has_flag_ter_or_furn(), i_at(), retroactively_fill_from_funnel(), TFLAG_INDOORS, tr_at(), and calendar::turn.

Referenced by actualize().

◆ find_clear_path()

std::vector< tripoint > map::find_clear_path ( const tripoint source,
const tripoint destination 
) const

Iteratively tries Bresenham lines with different biases until it finds a clear line or decides there isn't one.

returns the line found, which may be the straight line, but blocked.

Definition at line 6274 of file map.cpp.

6276{
6277 // TODO: Push this junk down into the Bresenham method, it's already doing it.
6278 const point d( destination.xy() - source.xy() );
6279 const point a( std::abs( d.x ) * 2, std::abs( d.y ) * 2 );
6280 const int dominant = std::max( a.x, a.y );
6281 const int minor = std::min( a.x, a.y );
6282 // This seems to be the method for finding the ideal start value for the error value.
6283 const int ideal_start_offset = minor - dominant / 2;
6284 const int start_sign = ( ideal_start_offset > 0 ) - ( ideal_start_offset < 0 );
6285 // Not totally sure of the derivation.
6286 const int max_start_offset = std::abs( ideal_start_offset ) * 2 + 1;
6287 for( int horizontal_offset = -1; horizontal_offset <= max_start_offset; ++horizontal_offset ) {
6288 int candidate_offset = horizontal_offset * start_sign;
6289 if( sees( source, destination, rl_dist( source, destination ), candidate_offset ) ) {
6290 return line_to( source, destination, candidate_offset, 0 );
6291 }
6292 }
6293 // If we couldn't find a clear LoS, just return the ideal one.
6294 return line_to( source, destination, ideal_start_offset, 0 );
6295}
bool sees(const tripoint &F, const tripoint &T, int range) const
Returns whether F sees T with a view range of range.
Definition: map.cpp:6142

References a, line_to(), minor, rl_dist(), sees(), point::x, tripoint::xy(), and point::y.

Referenced by mattack::boomer(), mattack::boomer_glow(), leap_actor::call(), mattack::flame(), projectile_attack(), mattack::ranged_pull(), target_ui::set_cursor_pos(), and ranged::targetable_creatures().

◆ find_furnitures_or_vparts_with_flag_in_radius()

std::list< tripoint > map::find_furnitures_or_vparts_with_flag_in_radius ( const tripoint center,
size_t  radius,
const std::string &  flag,
size_t  radiusz = 0 
)

returns positions of furnitures or vehicle parts with matching flag in the specified radius

Definition at line 8703 of file map.cpp.

8705{
8706 std::list<tripoint> locs;
8707 for( const auto &loc : points_in_radius( center, radius, radiusz ) ) {
8708 // workaround for ramp bridges
8709 int dz = 0;
8710 if( has_flag( TFLAG_RAMP_UP, loc ) ) {
8711 dz = 1;
8712 } else if( has_flag( TFLAG_RAMP_DOWN, loc ) ) {
8713 dz = -1;
8714 }
8715
8716 if( dz == 0 ) {
8717 if( has_flag_furn_or_vpart( flag, loc ) ) {
8718 locs.push_back( loc );
8719 }
8720 } else {
8721 const tripoint newloc( loc + tripoint( 0, 0, dz ) );
8722 if( has_flag_furn_or_vpart( flag, newloc ) ) {
8723 locs.push_back( newloc );
8724 }
8725 }
8726 }
8727
8728 return locs;
8729}
bool has_flag_furn_or_vpart(const std::string &flag, const tripoint &p) const
Definition: map.cpp:2357

References center, has_flag(), has_flag_furn_or_vpart(), points_in_radius(), TFLAG_RAMP_DOWN, and TFLAG_RAMP_UP.

Referenced by activity_handlers::operation_do_turn(), activity_handlers::operation_finish(), and player_on_couch().

◆ find_furnitures_with_flag_in_radius()

std::list< tripoint > map::find_furnitures_with_flag_in_radius ( const tripoint center,
size_t  radius,
const std::string &  flag,
size_t  radiusz = 0 
)

returns positions of furnitures with matching flag in the specified radius

Definition at line 8689 of file map.cpp.

8693{
8694 std::list<tripoint> furn_locs;
8695 for( const auto &furn_loc : points_in_radius( center, radius, radiusz ) ) {
8696 if( has_flag_furn( flag, furn_loc ) ) {
8697 furn_locs.push_back( furn_loc );
8698 }
8699 }
8700 return furn_locs;
8701}

References center, has_flag_furn(), and points_in_radius().

◆ flammable_items_at()

bool map::flammable_items_at ( const tripoint p,
int  threshold = 0 
)

Checks if there are any flammable items on the tile.

Parameters
ptile to check
thresholdFuel threshold (lower means worse fuels are accepted).

Definition at line 2636 of file map.cpp.

2637{
2638 if( !has_items( p ) ||
2640 // Sealed containers don't allow fire, so shouldn't allow setting the fire either
2641 return false;
2642 }
2643
2644 for( const auto &i : i_at( p ) ) {
2645 if( i.flammable( threshold ) ) {
2646 return true;
2647 }
2648 }
2649
2650 return false;
2651}
@ TFLAG_ALLOW_FIELD_EFFECT
Definition: mapdata.h:286

References has_flag(), has_items(), i_at(), TFLAG_ALLOW_FIELD_EFFECT, and TFLAG_SEALED.

Referenced by MapExtras::burned_ground_parser(), is_flammable(), firestarter_actor::moves_cost_by_fuel(), process_fields_in_submap(), and item::process_litcig().

◆ free_volume()

units::volume map::free_volume ( const tripoint p)

Definition at line 4230 of file map.cpp.

4231{
4232 return i_at( p ).free_volume();
4233}
units::volume free_volume() const
Definition: item_stack.cpp:141

References item_stack::free_volume(), and i_at().

Referenced by activity_on_turn_move_loot(), add_item_or_charges(), and advanced_inv_area::free_volume().

◆ function_over()

template<typename Functor >
void map::function_over ( const tripoint start,
const tripoint end,
Functor  fun 
) const
private

Runs a functor over given submaps over submaps in the area, getting next submap only when the current one "runs out" rather than every time.

gp in the functor is Grid (like get_submap_at_grid) coordinate of the submap, Will silently clip the area to map bounds.

Parameters
startStarting point for function
endEnd point for function
funFunction to run

Definition at line 8503 of file map.cpp.

8504{
8505 // start and end are just two points, end can be "before" start
8506 // Also clip the area to map area
8507 const tripoint min( std::max( std::min( start.x, end.x ), 0 ), std::max( std::min( start.y, end.y ),
8508 0 ), std::max( std::min( start.z, end.z ), -OVERMAP_DEPTH ) );
8509 const tripoint max( std::min( std::max( start.x, end.x ), SEEX * my_MAPSIZE - 1 ),
8510 std::min( std::max( start.y, end.y ), SEEY * my_MAPSIZE - 1 ), std::min( std::max( start.z, end.z ),
8511 OVERMAP_HEIGHT ) );
8512
8513 // Submaps that contain the bounding points
8514 const point min_sm( min.x / SEEX, min.y / SEEY );
8515 const point max_sm( max.x / SEEX, max.y / SEEY );
8516 // Z outermost, because submaps are flat
8517 tripoint gp;
8518 int &z = gp.z;
8519 int &smx = gp.x;
8520 int &smy = gp.y;
8521 for( z = min.z; z <= max.z; z++ ) {
8522 for( smx = min_sm.x; smx <= max_sm.x; smx++ ) {
8523 for( smy = min_sm.y; smy <= max_sm.y; smy++ ) {
8524 submap const *cur_submap = get_submap_at_grid( { smx, smy, z } );
8525 // Bounds on the submap coordinates
8526 const point sm_min( smx > min_sm.x ? 0 : min.x % SEEX, smy > min_sm.y ? 0 : min.y % SEEY );
8527 const point sm_max( smx < max_sm.x ? SEEX - 1 : max.x % SEEX,
8528 smy < max_sm.y ? SEEY - 1 : max.y % SEEY );
8529
8530 point lp;
8531 int &sx = lp.x;
8532 int &sy = lp.y;
8533 for( sx = sm_min.x; sx <= sm_max.x; ++sx ) {
8534 for( sy = sm_min.y; sy <= sm_max.y; ++sy ) {
8535 const iteration_state rval = fun( gp, cur_submap, lp );
8536 if( rval != ITER_CONTINUE ) {
8537 switch( rval ) {
8538 case ITER_SKIP_ZLEVEL:
8539 smx = my_MAPSIZE + 1;
8540 smy = my_MAPSIZE + 1;
8541 // Fall through
8542 case ITER_SKIP_SUBMAP:
8543 sx = SEEX;
8544 sy = SEEY;
8545 break;
8546 default:
8547 return;
8548 }
8549 }
8550 }
8551 }
8552 }
8553 }
8554 }
8555}
iteration_state
Enum used by functors in function_over to control execution.
Definition: map.h:1976

References get_submap_at_grid(), ITER_CONTINUE, ITER_SKIP_SUBMAP, ITER_SKIP_ZLEVEL, my_MAPSIZE, OVERMAP_DEPTH, OVERMAP_HEIGHT, SEEX, SEEY, sx, sy, point::x, tripoint::x, point::y, tripoint::y, and tripoint::z.

Referenced by scent_blockers().

◆ furn() [1/2]

furn_id map::furn ( const point p) const
inline

Definition at line 853 of file map.h.

853 {
854 return furn( tripoint( p, abs_sub.z ) );
855 }

References abs_sub, furn(), and tripoint::z.

◆ furn() [2/2]

furn_id map::furn ( const tripoint p) const

Definition at line 1348 of file map.cpp.

1349{
1350 if( !inbounds( p ) ) {
1351 return f_null;
1352 }
1353
1354 point l;
1355 submap *const current_submap = get_submap_at( p, l );
1356
1357 return current_submap->get_furn( l );
1358}
furn_id get_furn(const point &p) const
Definition: submap.h:86

References f_null, submap::get_furn(), get_submap_at(), and inbounds().

Referenced by computer_session::action_blood_anal(), computer_session::action_sample(), actualize(), ter_furn_transform::add_all_messages(), iexamine::arcfurnace_empty(), iexamine::arcfurnace_full(), iexamine::autoclave_full(), bash_furn_success(), bash_rating(), bash_resistance(), bash_strength(), bash_ter_furn(), board_up(), MapExtras::burned_ground_parser(), can_construct(), can_examine_at(), can_move_furniture(), construct::check_deconstruct(), vehicle::autodrive_controller::check_drivable(), deploy_tent_actor::check_intact(), close_door(), doors::close_door(), coverage(), create_anomaly(), MapExtras::dead_vegetation_parser(), iexamine::deployed_furniture(), destroy_furn(), displace_items_except_one_liquid(), game::do_turn(), construct::done_deconstruct(), editmap_hilight::draw(), draw_lab(), editmap::draw_main_ui_overlay(), drop_furniture(), Character::env_surgery_bonus(), examine(), game::examine(), game::extended_description(), computer_session::failure_destroy_blood(), farm_action(), feature< furn_id >(), iexamine::fertilize_plant(), talk_function::field_harvest(), activity_handlers::fill_liquid_do_turn(), find_base_construction(), find_potential_computer_point(), iexamine::fireplace(), Character::floor_bedding_warmth(), inventory::form_from_map(), furn(), furn_is_supported(), furnname(), generic_multi_activity_locations(), get_changed_ids_from_update(), activity_handlers::repair_activity_hack::anonymous_namespace{activity_handlers.cpp}::get_fake_tool(), get_furn_transforms_into(), get_hack_type(), get_harvest(), get_harvest_names(), get_keg_capacity(), grab(), game::grabbed_furn_move(), grow_plant(), activity_handlers::hacksaw_finish(), iexamine::harvest_plant(), has_adjacent_furniture_with(), has_flag_furn(), has_furn(), has_pre_terrain(), is_bashable(), is_bashable_furn(), iexamine::kiln_empty(), iexamine::kiln_full(), talk_function::loot_building(), map_stack::max_volume(), mill_activate(), iexamine::mill_finalize(), mill_load_food(), avatar_action::move(), move_cost(), obstacle_coverage(), om_harvest_furn(), iexamine::on_smoke_out(), open_door(), activity_handlers::oxytorch_finish(), tutorial_game::per_turn(), Character::place_corpse(), game::place_player(), mission_start::place_priest_diary(), activity_handlers::plant_seed_finish(), iexamine::portable_structure(), game::print_terrain_info(), item::process_fake_mill(), item::process_fake_smoke(), process_items_in_submap(), iexamine::quern_examine(), rad_scorch(), iexamine::reload_furniture(), resolve_regional_terrain_and_furniture(), set_item_map_or_vehicle(), smash(), smoker_activate(), smoker_finalize(), smoker_load_food(), iexamine::smoker_options(), fungal_effects::spread_fungus_one_tile(), ter_furn_transform::transform(), editmap::update_view_with_help(), pick_lock_actor::use(), use_charges(), iexamine::use_furn_fake_item(), game::walk_move(), water_from(), and workbench_crafting_speed_multiplier().

◆ furn_set() [1/2]

void map::furn_set ( const point p,
const furn_id new_furniture 
)
inline

Definition at line 865 of file map.h.

865 {
866 furn_set( tripoint( p, abs_sub.z ), new_furniture );
867 }

References abs_sub, furn_set(), and tripoint::z.

◆ furn_set() [2/2]

void map::furn_set ( const tripoint p,
const furn_id new_furniture,
cata::poly_serialized< active_tile_data new_active = nullptr 
)

Sets the furniture at given position.

Parameters
pPosition within the map
new_furnitureId of new furniture
new_activeOverride default active tile of new furniture

Definition at line 1360 of file map.cpp.

1362{
1363 if( !inbounds( p ) ) {
1364 return;
1365 }
1366
1367 point l;
1368 submap *const current_submap = get_submap_at( p, l );
1369 const furn_id old_id = current_submap->get_furn( l );
1370 if( old_id == new_furniture ) {
1371 // Nothing changed
1372 return;
1373 }
1374
1375 current_submap->set_furn( l, new_furniture );
1376
1377 // Set the dirty flags
1378 const furn_t &old_t = old_id.obj();
1379 const furn_t &new_t = new_furniture.obj();
1380
1381 // If player has grabbed this furniture and it's no longer grabbable, release the grab.
1382 if( g->u.get_grab_type() == OBJECT_FURNITURE && g->u.grab_point == p && !new_t.is_movable() ) {
1383 add_msg( _( "The %s you were grabbing is destroyed!" ), old_t.name() );
1384 g->u.grab( OBJECT_NONE );
1385 }
1386 // If a creature was crushed under a rubble -> free it
1387 if( old_id == f_rubble && new_furniture == f_null ) {
1388 Creature *c = g->critter_at( p );
1389 if( c ) {
1390 c->remove_effect( effect_crushed );
1391 }
1392 }
1393 if( new_t.has_flag( "EMITTER" ) ) {
1394 field_furn_locs.push_back( p );
1395 }
1396 if( old_t.transparent != new_t.transparent ) {
1399 }
1400
1401 if( old_t.has_flag( TFLAG_INDOORS ) != new_t.has_flag( TFLAG_INDOORS ) ) {
1403 }
1404
1405 if( old_t.has_flag( TFLAG_NO_FLOOR ) != new_t.has_flag( TFLAG_NO_FLOOR ) ) {
1408 }
1409
1410 if( old_t.has_flag( TFLAG_SUN_ROOF_ABOVE ) != new_t.has_flag( TFLAG_SUN_ROOF_ABOVE ) ) {
1411 set_floor_cache_dirty( p.z + 1 );
1412 }
1413
1415
1417
1418 // TODO: Limit to changes that affect move cost, traps and stairs
1420
1421 // Make sure the furniture falls if it needs to
1422 support_dirty( p );
1423 tripoint above( p.xy(), p.z + 1 );
1424 // Make sure that if we supported something and no longer do so, it falls down
1425 support_dirty( above );
1426
1427 if( old_t.active ) {
1428 current_submap->active_furniture.erase( point_sm_ms( l ) );
1429 // TODO: Only for g->m? Observer pattern?
1431 }
1432 if( new_t.active || new_active ) {
1434 if( new_active ) {
1435 atd = new_active;
1436 } else {
1437 atd = new_t.active->clone();
1438 atd->set_last_updated( calendar::turn );
1439 }
1440 current_submap->active_furniture[point_sm_ms( l )] = atd;
1442 }
1443}
Copyable unique_ptr that writes and reads objects of derived types.
void on_changed(const tripoint_abs_ms &p)
Updates grid at given global map square coordinate.
void set_floor_cache_dirty(const int zlev)
Definition: map.h:448
void set_memory_seen_cache_dirty(const tripoint &p)
Definition: map.h:463
std::map< point_sm_ms, cata::poly_serialized< active_tile_data > > active_furniture
Definition: submap.h:250
void set_furn(const point &p, furn_id furn)
Definition: submap.h:90
coords::coord_point< point, coords::origin::submap, coords::ms > point_sm_ms
Definition: coordinates.h:473
coords::coord_point< tripoint, coords::origin::abs, coords::ms > tripoint_abs_ms
Definition: coordinates.h:486
distribution_grid_tracker & get_distribution_grid_tracker()
Returns distribution grid tracker that is a part of the global game *g.
Definition: game.cpp:12193
@ OBJECT_NONE
Definition: enums.h:187
@ OBJECT_FURNITURE
Definition: enums.h:197
bool is_movable() const
Definition: mapdata.cpp:1516
cata::poly_serialized< active_tile_data > active
Definition: mapdata.h:519
std::string name() const
Definition: mapdata.cpp:511

References _, furn_t::active, submap::active_furniture, add_msg(), c, effect_crushed, f_null, f_rubble, field_furn_locs, g, get_distribution_grid_tracker(), submap::get_furn(), get_submap_at(), getabs(), map_data_common_t::has_flag(), inbounds(), invalidate_max_populated_zlev(), furn_t::is_movable(), map_data_common_t::name(), int_id< T >::obj(), OBJECT_FURNITURE, OBJECT_NONE, distribution_grid_tracker::on_changed(), set_floor_cache_dirty(), submap::set_furn(), set_memory_seen_cache_dirty(), set_outside_cache_dirty(), set_pathfinding_cache_dirty(), set_seen_cache_dirty(), set_transparency_cache_dirty(), support_dirty(), TFLAG_INDOORS, TFLAG_NO_FLOOR, TFLAG_SUN_ROOF_ABOVE, map_data_common_t::transparent, calendar::turn, tripoint::xy(), and tripoint::z.

Referenced by iexamine::aggie_plant(), grid_furn_transform_queue::apply(), jmapgen_sign::apply(), jmapgen_vending_machine::apply(), jmapgen_toilet::apply(), jmapgen_gaspump::apply(), jmapgen_furniture::apply(), jmapgen_terrain::apply(), jmapgen_computer::apply(), jmapgen_sealed_item::apply(), jmapgen_setmap::apply(), apply< furn_t >(), iexamine::arcfurnace_empty(), iexamine::arcfurnace_full(), iexamine::autoclave_full(), bash_furn_success(), board_up(), MapExtras::burned_ground_parser(), activity_handlers::clear_rubble_finish(), close_door(), collapse_at(), collapse_invalid_suspension(), complete_construction(), activity_handlers::cracking_finish(), create_anomaly(), MapExtras::dead_vegetation_parser(), iexamine::deployed_furniture(), displace_items_except_one_liquid(), construct::done_deconstruct(), draw_circle_furn(), draw_lab(), draw_line_furn(), draw_rough_circle_furn(), draw_square_furn(), drop_furniture(), iexamine::egg_sack_generic(), farm_action(), iexamine::fertilize_plant(), talk_function::field_harvest(), activity_handlers::fill_liquid_do_turn(), dig_activity_actor::finish(), hacking_activity_actor::finish(), iexamine::fireplace(), iexamine::flower_cactus(), iexamine::flower_dahlia(), iexamine::flower_marloss(), iexamine::flower_poppy(), mapgen_function_json_base::formatted_set_incredibly_simple(), mapf::formatted_set_simple(), iexamine::fungus(), furn_set(), iexamine::fvat_empty(), iexamine::fvat_full(), game::grabbed_furn_move(), grow_plant(), activity_handlers::hacksaw_finish(), iexamine::harvest_furn(), iexamine::harvest_furn_nectar(), iexamine::harvest_plant(), iexamine::kiln_empty(), iexamine::kiln_full(), talk_function::loot_building(), make_rubble(), mapgen_forest(), mapgen_forest_trail_curved(), mapgen_forest_trail_four_way(), mapgen_forest_trail_straight(), mapgen_forest_trail_tee(), mapgen_lake_shore(), mapgen_tutorial(), iexamine::migo_nerve_cluster(), mill_activate(), iexamine::mill_finalize(), MapExtras::mx_burned_ground(), MapExtras::mx_clay_deposit(), MapExtras::mx_grave(), MapExtras::mx_house_spider(), MapExtras::mx_minefield(), MapExtras::mx_pond(), MapExtras::mx_roadworks(), MapExtras::mx_spider(), MapExtras::mx_supplydrop(), om_harvest_furn(), open_door(), iexamine::open_safe(), activity_handlers::oxytorch_finish(), place_toilet(), place_vending(), activity_handlers::plant_seed_finish(), iexamine::portable_structure(), process_fields_in_submap(), iexamine::quern_examine(), rad_scorch(), mission_start::ranch_nurse_9(), mission_start::ranch_scavenger_3(), resolve_regional_terrain_and_furniture(), iexamine::safe(), science_room(), set(), smoker_activate(), smoker_finalize(), iexamine::smoker_options(), fungal_effects::spread_fungus_one_tile(), ter_or_furn_set(), ter_furn_transform::transform(), deploy_furn_actor::use(), deploy_tent_actor::use(), and game::vertical_move().

◆ furnname() [1/2]

std::string map::furnname ( const point p)
inline

Definition at line 869 of file map.h.

869 {
870 return furnname( tripoint( p, abs_sub.z ) );
871 }
std::string furnname(const tripoint &p)
Definition: map.cpp:1469

References abs_sub, furnname(), and tripoint::z.

◆ furnname() [2/2]

std::string map::furnname ( const tripoint p)

Definition at line 1469 of file map.cpp.

1470{
1471 const furn_t &f = furn( p ).obj();
1472 if( f.has_flag( "PLANT" ) ) {
1473 // Can't use item_stack::only_item() since there might be fertilizer
1474 map_stack items = i_at( p );
1475 const map_stack::iterator seed = std::find_if( items.begin(), items.end(), []( const item & it ) {
1476 return it.is_seed();
1477 } );
1478 if( seed == items.end() ) {
1479 debugmsg( "Missing seed for plant at (%d, %d, %d)", p.x, p.y, p.z );
1480 return "null";
1481 }
1482 const std::string &plant = seed->get_plant_name();
1483 return string_format( "%s (%s)", f.name(), plant );
1484 } else {
1485 return f.name();
1486 }
1487}
iterator begin()
Definition: item_stack.cpp:28
iterator end()
Definition: item_stack.cpp:33
Definition: map.h:105
int seed(player *, item *, bool, const tripoint &)
Definition: iuse.cpp:6000

References item_stack::begin(), debugmsg, item_stack::end(), furn(), map_data_common_t::has_flag(), i_at(), map_data_common_t::name(), int_id< T >::obj(), plant, iuse::seed(), string_format(), tripoint::x, tripoint::y, and tripoint::z.

Referenced by apply_lock_picking_tool(), apply_prying_tool(), activity_handlers::clear_rubble_finish(), iexamine::egg_sack_generic(), iexamine::fireplace(), iexamine::flower_cactus(), iexamine::flower_dahlia(), iexamine::flower_marloss(), iexamine::flower_poppy(), iexamine::fungus(), furnname(), grab(), harvest_common(), iexamine::locked_object(), iexamine::locked_object_pickable(), name(), game::place_player(), game::print_terrain_info(), iexamine::reload_furniture(), iexamine::rubble(), smash(), and deploy_tent_actor::use().

◆ gas_can_spread_to()

bool map::gas_can_spread_to ( field_entry cur,
const tripoint src,
const tripoint dst 
)
private

Definition at line 211 of file map_field.cpp.

212{
213 maptile dst_tile = maptile_at( dst );
214 const field_entry *tmpfld = dst_tile.get_field().find_field( cur.get_field_type() );
215 // Candidates are existing weaker fields or navigable/flagged tiles with no field.
216 if( tmpfld == nullptr || tmpfld->get_field_intensity() < cur.get_field_intensity() ) {
217 const ter_t &ter = dst_tile.get_ter_t();
218 const furn_t &frn = dst_tile.get_furn_t();
219 return !obstructed_by_vehicle_rotation( src, dst ) &&
220 ( ter_furn_movecost( ter, frn ) > 0 || ter_furn_has_flag( ter, frn, TFLAG_PERMEABLE ) );
221 }
222 return false;
223}
bool ter_furn_has_flag(const ter_t &ter, const furn_t &furn, const ter_bitflags flag)
Definition: map_field.cpp:161
static int ter_furn_movecost(const ter_t &ter, const furn_t &furn)
Definition: map_field.cpp:166
@ TFLAG_PERMEABLE
Definition: mapdata.h:304
const ter_t & get_ter_t() const
Definition: submap.h:300
const field & get_field() const
Definition: submap.h:304
const furn_t & get_furn_t() const
Definition: submap.h:297

References field::find_field(), maptile::get_field(), field_entry::get_field_intensity(), field_entry::get_field_type(), maptile::get_furn_t(), maptile::get_ter_t(), maptile_at(), obstructed_by_vehicle_rotation(), ter(), ter_furn_has_flag(), ter_furn_movecost(), and TFLAG_PERMEABLE.

Referenced by spread_gas().

◆ gas_spread_to()

void map::gas_spread_to ( field_entry cur,
maptile dst,
const tripoint p 
)
private

Definition at line 225 of file map_field.cpp.

226{
227 const field_type_id current_type = cur.get_field_type();
228 const time_duration current_age = cur.get_field_age();
229 const int current_intensity = cur.get_field_intensity();
230 field_entry *f = dst.find_field( current_type );
231 // Nearby gas grows thicker, and ages are shared.
232 const time_duration age_fraction = current_age / current_intensity;
233 if( f != nullptr ) {
235 cur.set_field_intensity( current_intensity - 1 );
236 f->set_field_age( f->get_field_age() + age_fraction );
237 cur.set_field_age( current_age - age_fraction );
238 // Or, just create a new field.
239 } else if( add_field( p, current_type, 1, 0_turns ) ) {
240 f = dst.find_field( current_type );
241 if( f != nullptr ) {
242 f->set_field_age( age_fraction );
243 } else {
244 debugmsg( "While spreading the gas, field was added but doesn't exist." );
245 }
246 cur.set_field_intensity( current_intensity - 1 );
247 cur.set_field_age( current_age - age_fraction );
248 }
249}
int set_field_intensity(int new_intensity)
Definition: field.cpp:126
field_entry * find_field(const field_type_id &field_to_find)
Definition: submap.h:308

References add_field(), debugmsg, maptile::find_field(), field_entry::get_field_age(), field_entry::get_field_intensity(), field_entry::get_field_type(), field_entry::set_field_age(), and field_entry::set_field_intensity().

Referenced by spread_gas().

◆ generate()

void map::generate ( const tripoint p,
const time_point when 
)

Definition at line 107 of file mapgen.cpp.

108{
109 dbg( DL::Info ) << "map::generate( g[" << g.get() << "], p[" << p <<
110 "], when[" << to_string( when ) << "] )";
111
112 set_abs_sub( p );
113
114 // First we have to create new submaps and initialize them to 0 all over
115 // We create all the submaps, even if we're not a tinymap, so that map
116 // generation which overflows won't cause a crash. At the bottom of this
117 // function, we save the upper-left 4 submaps, and delete the rest.
118 // Mapgen is not z-level aware yet. Only actually initialize current z-level
119 // because other submaps won't be touched.
120 for( int gridx = 0; gridx < my_MAPSIZE; gridx++ ) {
121 for( int gridy = 0; gridy < my_MAPSIZE; gridy++ ) {
122 const size_t grid_pos = get_nonant( { gridx, gridy, p.z } );
123 if( getsubmap( grid_pos ) ) {
124 debugmsg( "Submap already exists at (%d, %d, %d)", gridx, gridy, p.z );
125 continue;
126 }
127 setsubmap( grid_pos, new submap() );
128 // TODO: memory leak if the code below throws before the submaps get stored/deleted!
129 }
130 }
131 // x, and y are submap coordinates, convert to overmap terrain coordinates
132 // TODO: fix point types
133 tripoint_abs_omt abs_omt( sm_to_omt_copy( p ) );
134 oter_id terrain_type = overmap_buffer.ter( abs_omt );
135
136 // This attempts to scale density of zombies inversely with distance from the nearest city.
137 // In other words, make city centers dense and perimeters sparse.
138 float density = 0.0;
139 for( int i = -MON_RADIUS; i <= MON_RADIUS; i++ ) {
140 for( int j = -MON_RADIUS; j <= MON_RADIUS; j++ ) {
141 density += overmap_buffer.ter( abs_omt + point( i, j ) )->get_mondensity();
142 }
143 }
144 density = density / 100;
145
146 mapgendata dat( abs_omt, *this, density, when, nullptr );
147 draw_map( dat );
148
149 // At some point, we should add region information so we can grab the appropriate extras
150 map_extras ex = region_settings_map["default"].region_extras[terrain_type->get_extras()];
151 if( ex.chance > 0 && one_in( ex.chance ) ) {
152 std::string *extra = ex.values.pick();
153 if( extra == nullptr ) {
154 debugmsg( "failed to pick extra for type %s", terrain_type->get_extras() );
155 } else {
156 MapExtras::apply_function( *( ex.values.pick() ), *this, abs_sub );
157 }
158 }
159
160 const auto &spawns = terrain_type->get_static_spawns();
161
162 float spawn_density = 1.0f;
163 if( MonsterGroupManager::is_animal( spawns.group ) ) {
164 spawn_density = get_option< float >( "SPAWN_ANIMAL_DENSITY" );
165 } else {
166 spawn_density = get_option< float >( "SPAWN_DENSITY" );
167 }
168
169 // Apply a multiplier to the number of monsters for really high densities.
170 float odds_after_density = spawns.chance * spawn_density;
171 const float max_odds = 100 - ( 100 - spawns.chance ) / 2.0;
172 float density_multiplier = 1.0f;
173 if( odds_after_density > max_odds ) {
174 density_multiplier = 1.0f * odds_after_density / max_odds;
175 odds_after_density = max_odds;
176 }
177 const int spawn_count = roll_remainder( density_multiplier );
178
179 if( spawns.group && x_in_y( odds_after_density, 100 ) ) {
180 int pop = spawn_count * rng( spawns.population.min, spawns.population.max );
181 for( ; pop > 0; pop-- ) {
182 MonsterGroupResult spawn_details = MonsterGroupManager::GetResultFromGroup( spawns.group, &pop );
183 if( !spawn_details.name ) {
184 continue;
185 }
186 if( const cata::optional<tripoint> pt =
187 random_point( *this, [this]( const tripoint & n ) {
188 return passable( n );
189 } ) ) {
190 add_spawn( spawn_details.name, spawn_details.pack_size, *pt );
191 }
192 }
193 }
194
195 // Okay, we know who are neighbors are. Let's draw!
196 // And finally save used submaps and delete the rest.
197 for( int i = 0; i < my_MAPSIZE; i++ ) {
198 for( int j = 0; j < my_MAPSIZE; j++ ) {
199 dbg( DL::Info ) << "map::generate: submap (" << i << "," << j << ")";
200
201 const tripoint pos( i, j, p.z );
202 if( i <= 1 && j <= 1 ) {
203 saven( pos );
204 } else {
205 const size_t grid_pos = get_nonant( pos );
206 delete getsubmap( grid_pos );
207 setsubmap( grid_pos, nullptr );
208 }
209 }
210 }
211}
std::string to_string(const time_duration &d)
Returns a string showing a duration.
Definition: calendar.cpp:327
static bool is_animal(const mongroup_id &group)
Definition: mongroup.cpp:401
static MonsterGroupResult GetResultFromGroup(const mongroup_id &group, int *quantity=nullptr)
Definition: mongroup.cpp:98
void saven(const tripoint &grid)
Definition: map.cpp:6950
void set_abs_sub(const tripoint &p)
Sets abs_sub, see there.
Definition: map.cpp:8283
void draw_map(mapgendata &dat)
Definition: mapgen.cpp:2891
submap * getsubmap(size_t grididx) const
Get the submap pointer with given index in grid, the index must be valid!
Definition: map.cpp:8293
void add_spawn(const mtype_id &type, int count, const tripoint &p, bool friendly=false, int faction_id=-1, int mission_id=-1, const std::string &name="NONE") const
Definition: mapgen.cpp:5585
bool passable(const tripoint &p) const
Definition: map.cpp:1800
Contains various information regarding the individual mapgen instance (generating a specific part of ...
Definition: mapgendata.h:36
const oter_id & ter(const tripoint_abs_omt &p)
Returns the overmap terrain at the given OMT coordinates.
point sm_to_omt_copy(const point &p)
static constexpr int MON_RADIUS
Definition: mapgen.cpp:101
void apply_function(const string_id< map_extra > &id, map &m, const tripoint &abs_sub)
t_regional_settings_map region_settings_map
Definition: overmap.cpp:186
mtype_id name
Definition: mongroup.h:53
unsigned int chance
weighted_int_list< std::string > values
const std::string & get_extras() const
Definition: omdata.h:237
const overmap_static_spawns & get_static_spawns() const
Definition: omdata.h:245
int get_mondensity() const
Definition: omdata.h:241

References abs_sub, add_spawn(), MapExtras::apply_function(), map_extras::chance, dbg, debugmsg, draw_map(), g, oter_t::get_extras(), oter_t::get_mondensity(), get_nonant(), oter_t::get_static_spawns(), MonsterGroupManager::GetResultFromGroup(), getsubmap(), Info, MonsterGroupManager::is_animal(), MON_RADIUS, my_MAPSIZE, MonsterGroupResult::name, one_in(), overmap_buffer, MonsterGroupResult::pack_size, passable(), random_point(), region_settings_map, rng(), roll_remainder(), saven(), set_abs_sub(), setsubmap(), sm_to_omt_copy(), overmapbuffer::ter(), to_string(), map_extras::values, x_in_y(), and tripoint::z.

Referenced by farm_action(), defense_game::init_map(), loadn(), and editmap::mapgen_preview().

◆ generate_lightmap()

void map::generate_lightmap ( int  zlev)
protected

Definition at line 400 of file lightmap.cpp.

401{
402 auto &map_cache = get_cache( zlev );
403 auto &lm = map_cache.lm;
404 auto &sm = map_cache.sm;
405 auto &outside_cache = map_cache.outside_cache;
406 auto &prev_floor_cache = get_cache( clamp( zlev + 1, -OVERMAP_DEPTH, OVERMAP_DEPTH ) ).floor_cache;
407 bool top_floor = zlev == OVERMAP_DEPTH;
408 std::memset( lm, 0, sizeof( lm ) );
409 std::memset( sm, 0, sizeof( sm ) );
410
411 /* Bulk light sources wastefully cast rays into neighbors; a burning hospital can produce
412 significant slowdown, so for stuff like fire and lava:
413 * Step 1: Store the position and luminance in buffer via add_light_source, for efficient
414 checking of neighbors.
415 * Step 2: After everything else, iterate buffer and apply_light_source only in non-redundant
416 directions
417 * Step 3: ????
418 * Step 4: Profit!
419 */
420 auto &light_source_buffer = map_cache.light_source_buffer;
421 std::memset( light_source_buffer, 0, sizeof( light_source_buffer ) );
422
423 constexpr std::array<int, 4> dir_x = { { 0, -1, 1, 0 } }; // [0]
424 constexpr std::array<int, 4> dir_y = { { -1, 0, 0, 1 } }; // [1][X][2]
425 constexpr std::array<int, 4> dir_d = { { 90, 0, 180, 270 } }; // [3]
426 constexpr std::array<std::array<quadrant, 2>, 4> dir_quadrants = { {
431 }
432 };
433
434 const float natural_light = g->natural_light_level( zlev );
435
436 build_sunlight_cache( zlev );
437
439 for( npc &guy : g->all_npcs() ) {
441 }
442
443 std::vector<std::pair<tripoint, float>> lm_override;
444 // Traverse the submaps in order
445 for( int smx = 0; smx < my_MAPSIZE; ++smx ) {
446 for( int smy = 0; smy < my_MAPSIZE; ++smy ) {
447 const auto cur_submap = get_submap_at_grid( { smx, smy, zlev } );
448
449 for( int sx = 0; sx < SEEX; ++sx ) {
450 for( int sy = 0; sy < SEEY; ++sy ) {
451 const int x = sx + smx * SEEX;
452 const int y = sy + smy * SEEY;
453 const tripoint p( x, y, zlev );
454 // Project light into any openings into buildings.
455 if( !outside_cache[p.x][p.y] || ( !top_floor && prev_floor_cache[p.x][p.y] ) ) {
456 // Apply light sources for external/internal divide
457 for( int i = 0; i < 4; ++i ) {
458 point neighbour = p.xy() + point( dir_x[i], dir_y[i] );
459 if( lightmap_boundaries.contains( neighbour )
460 && outside_cache[neighbour.x][neighbour.y] &&
461 ( top_floor || !prev_floor_cache[neighbour.x][neighbour.y] )
462 ) {
463 const float source_light =
464 std::min( natural_light, lm[neighbour.x][neighbour.y].max() );
466 update_light_quadrants( lm[p.x][p.y], source_light, quadrant::default_ );
467 apply_directional_light( p, dir_d[i], source_light );
468 } else {
469 update_light_quadrants( lm[p.x][p.y], source_light, dir_quadrants[i][0] );
470 update_light_quadrants( lm[p.x][p.y], source_light, dir_quadrants[i][1] );
471 }
472 }
473 }
474 }
475
476 if( cur_submap->get_lum( { sx, sy } ) && has_items( p ) ) {
477 auto items = i_at( p );
478 add_light_from_items( p, items.begin(), items.end() );
479 }
480
481 const ter_id terrain = cur_submap->get_ter( { sx, sy } );
482 if( terrain->light_emitted > 0 ) {
483 add_light_source( p, terrain->light_emitted );
484 }
485 const furn_id furniture = cur_submap->get_furn( {sx, sy } );
486 if( furniture->light_emitted > 0 ) {
487 add_light_source( p, furniture->light_emitted );
488 }
489
490 for( auto &fld : cur_submap->get_field( { sx, sy } ) ) {
491 const field_entry *cur = &fld.second;
492 const int light_emitted = cur->light_emitted();
493 if( light_emitted > 0 ) {
494 add_light_source( p, light_emitted );
495 }
496 const float light_override = cur->local_light_override();
497 if( light_override >= 0.0 ) {
498 lm_override.push_back( std::pair<tripoint, float>( p, light_override ) );
499 }
500 }
501 }
502 }
503 }
504 }
505
506 for( monster &critter : g->all_monsters() ) {
507 if( critter.is_hallucination() ) {
508 continue;
509 }
510 const tripoint &mp = critter.pos();
511 if( inbounds( mp ) ) {
512 if( critter.has_effect( effect_onfire ) ) {
513 apply_light_source( mp, 8 );
514 }
515 // TODO: [lightmap] Attach natural light brightness to creatures
516 // TODO: [lightmap] Allow creatures to have light attacks (i.e.: eyebot)
517 // TODO: [lightmap] Allow creatures to have facing and arc lights
518 if( critter.type->luminance > 0 ) {
519 apply_light_source( mp, critter.type->luminance );
520 }
521 }
522 }
523
524 // Apply any vehicle light sources
525 VehicleList vehs = get_vehicles();
526 for( auto &vv : vehs ) {
527 vehicle *v = vv.v;
528
529 auto lights = v->lights( true );
530
531 float veh_luminance = 0.0;
532 float iteration = 1.0;
533
534 for( const auto pt : lights ) {
535 const auto &vp = pt->info();
536 if( vp.has_flag( VPFLAG_CONE_LIGHT ) ||
537 vp.has_flag( VPFLAG_WIDE_CONE_LIGHT ) ) {
538 veh_luminance += vp.bonus / iteration;
539 iteration = iteration * 1.1;
540 }
541 }
542
543 for( const auto pt : lights ) {
544 const auto &vp = pt->info();
545 tripoint src = v->global_part_pos3( *pt );
546
547 if( !inbounds( src ) ) {
548 continue;
549 }
550
551 if( vp.has_flag( VPFLAG_CONE_LIGHT ) ) {
552 if( veh_luminance > lit_level::LIT ) {
553 add_light_source( src, M_SQRT2 ); // Add a little surrounding light
554 apply_light_arc( src, v->face.dir() + pt->direction, veh_luminance,
555 45_degrees );
556 }
557
558 } else if( vp.has_flag( VPFLAG_WIDE_CONE_LIGHT ) ) {
559 if( veh_luminance > lit_level::LIT ) {
560 add_light_source( src, M_SQRT2 ); // Add a little surrounding light
561 apply_light_arc( src, v->face.dir() + pt->direction, veh_luminance,
562 90_degrees );
563 }
564
565 } else if( vp.has_flag( VPFLAG_HALF_CIRCLE_LIGHT ) ) {
566 add_light_source( src, M_SQRT2 ); // Add a little surrounding light
567 apply_light_arc( src, v->face.dir() + pt->direction, vp.bonus, 180_degrees );
568
569 } else if( vp.has_flag( VPFLAG_CIRCLE_LIGHT ) ) {
570 const bool odd_turn = calendar::once_every( 2_turns );
571 if( ( odd_turn && vp.has_flag( VPFLAG_ODDTURN ) ) ||
572 ( !odd_turn && vp.has_flag( VPFLAG_EVENTURN ) ) ||
573 ( !( vp.has_flag( VPFLAG_EVENTURN ) || vp.has_flag( VPFLAG_ODDTURN ) ) ) ) {
574
575 add_light_source( src, vp.bonus );
576 }
577
578 } else {
579 add_light_source( src, vp.bonus );
580 }
581 }
582
583 for( const vpart_reference &vp : v->get_all_parts() ) {
584 const size_t p = vp.part_index();
585 const tripoint pp = vp.pos();
586 if( !inbounds( pp ) ) {
587 continue;
588 }
589 if( vp.has_feature( VPFLAG_CARGO ) && !vp.has_feature( "COVERED" ) ) {
590 add_light_from_items( pp, v->get_items( static_cast<int>( p ) ).begin(),
591 v->get_items( static_cast<int>( p ) ).end() );
592 }
593 }
594 }
595
596 /* Now that we have position and intensity of all bulk light sources, apply_ them
597 This may seem like extra work, but take a 12x12 raging inferno:
598 unbuffered: (12^2)*(160*4) = apply_light_ray x 92160
599 buffered: (12*4)*(160) = apply_light_ray x 7680
600 */
601 const tripoint cache_start( 0, 0, zlev );
602 const tripoint cache_end( LIGHTMAP_CACHE_X, LIGHTMAP_CACHE_Y, zlev );
603 for( const tripoint &p : points_in_rectangle( cache_start, cache_end ) ) {
604 if( light_source_buffer[p.x][p.y] > 0.0 ) {
605 apply_light_source( p, light_source_buffer[p.x][p.y] );
606 }
607 }
608 for( const std::pair<tripoint, float> &elem : lm_override ) {
609 lm[elem.first.x][elem.first.y].fill( elem.second );
610 }
611}
float light_emitted() const
Definition: field.cpp:69
float local_light_override() const
Definition: field.cpp:74
float light_transparency(const tripoint &p) const
Definition: lightmap.cpp:660
void apply_directional_light(const tripoint &p, int direction, float luminance)
Definition: lightmap.cpp:1624
void build_sunlight_cache(int pzlev)
Definition: lightmap.cpp:249
void add_light_from_items(const tripoint &p, item_stack::iterator begin, item_stack::iterator end)
Definition: lightmap.cpp:64
void apply_character_light(Character &p)
Definition: lightmap.cpp:227
Definition: npc.h:781
units::angle dir() const
Definition: tileray.cpp:74
std::vector< vehicle_part * > lights(bool active=false)
Get all vehicle lights (excluding any that are destroyed)
Definition: vehicle.cpp:4642
vehicle_stack get_items(int part) const
Definition: vehicle.cpp:5468
bool once_every(const time_duration &event_frequency)
Predicate to handle rate-limiting.
Definition: calendar.cpp:490
@ VPFLAG_CONE_LIGHT
Definition: veh_type.h:35
@ VPFLAG_CIRCLE_LIGHT
Definition: veh_type.h:38
@ VPFLAG_CARGO
Definition: veh_type.h:62
@ VPFLAG_EVENTURN
Definition: veh_type.h:33
@ VPFLAG_WIDE_CONE_LIGHT
Definition: veh_type.h:36
@ VPFLAG_ODDTURN
Definition: veh_type.h:34
@ VPFLAG_HALF_CIRCLE_LIGHT
Definition: veh_type.h:37

References add_light_from_items(), add_light_source(), apply_character_light(), apply_directional_light(), apply_light_arc(), apply_light_source(), item_stack::begin(), build_sunlight_cache(), clamp(), default_, tileray::dir(), effect_onfire, item_stack::end(), vehicle::face, level_cache::floor_cache, furniture, g, vehicle::get_all_parts(), get_cache(), vehicle::get_items(), get_player_character(), get_submap_at_grid(), get_vehicles(), vehicle::global_part_pos3(), has_items(), i_at(), inbounds(), field_entry::light_emitted(), light_transparency(), LIGHT_TRANSPARENCY_SOLID, lightmap_boundaries, LIGHTMAP_CACHE_X, LIGHTMAP_CACHE_Y, vehicle::lights(), LIT, field_entry::local_light_override(), M_SQRT2, my_MAPSIZE, NE, NW, calendar::once_every(), OVERMAP_DEPTH, points_in_rectangle(), SE, SEEX, SEEY, coords::sm, SW, sx, sy, terrain, update_light_quadrants(), VPFLAG_CARGO, VPFLAG_CIRCLE_LIGHT, VPFLAG_CONE_LIGHT, VPFLAG_EVENTURN, VPFLAG_HALF_CIRCLE_LIGHT, VPFLAG_ODDTURN, VPFLAG_WIDE_CONE_LIGHT, point::x, tripoint::x, tripoint::xy(), point::y, and tripoint::y.

Referenced by build_map_cache().

◆ get_abs_sub()

◆ get_active_items_in_radius() [1/2]

std::list< item_location > map::get_active_items_in_radius ( const tripoint center,
int  radius 
) const

Definition at line 8643 of file map.cpp.

8645{
8647}
std::list< item_location > get_active_items_in_radius(const tripoint &center, int radius) const
Definition: map.cpp:8643

References center, get_active_items_in_radius(), and none.

Referenced by npc::find_corpse_to_pulp(), npc::find_dangerous_explosives(), and get_active_items_in_radius().

◆ get_active_items_in_radius() [2/2]

std::list< item_location > map::get_active_items_in_radius ( const tripoint center,
int  radius,
special_item_type  type 
) const

Definition at line 8649 of file map.cpp.

8651{
8652 std::list<item_location> result;
8653
8654 const point minp( center.xy() + point( -radius, -radius ) );
8655 const point maxp( center.xy() + point( radius, radius ) );
8656
8657 const point ming( std::max( minp.x / SEEX, 0 ),
8658 std::max( minp.y / SEEY, 0 ) );
8659 const point maxg( std::min( maxp.x / SEEX, my_MAPSIZE - 1 ),
8660 std::min( maxp.y / SEEY, my_MAPSIZE - 1 ) );
8661
8662 for( const tripoint &abs_submap_loc : submaps_with_active_items ) {
8663 const tripoint submap_loc{ -abs_sub.xy() + abs_submap_loc };
8664 if( submap_loc.x < ming.x || submap_loc.y < ming.y ||
8665 submap_loc.x > maxg.x || submap_loc.y > maxg.y ) {
8666 continue;
8667 }
8668 const point sm_offset( submap_loc.x * SEEX, submap_loc.y * SEEY );
8669
8670 submap *sm = get_submap_at_grid( submap_loc );
8671 std::vector<item_reference> items = type == special_item_type::none ? sm->active_items.get() :
8672 sm->active_items.get_special( type );
8673 for( const auto &elem : items ) {
8674 const tripoint pos( sm_offset + elem.location, submap_loc.z );
8675
8676 if( rl_dist( pos, center ) > radius ) {
8677 continue;
8678 }
8679
8680 if( elem.item_ref ) {
8681 result.emplace_back( map_cursor( pos ), elem.item_ref.get() );
8682 }
8683 }
8684 }
8685
8686 return result;
8687}

References abs_sub, center, get_submap_at_grid(), my_MAPSIZE, none, rl_dist(), SEEX, SEEY, coords::sm, submaps_with_active_items, type, point::x, tripoint::xy(), and point::y.

◆ get_cache()

◆ get_cache_ref()

◆ get_creatures_in_radius()

std::list< Creature * > map::get_creatures_in_radius ( const tripoint center,
size_t  radius,
size_t  radiusz = 0 
)

returns creatures in specified radius

Definition at line 8731 of file map.cpp.

8733{
8734 std::list<Creature *> creatures;
8735 for( const auto &loc : points_in_radius( center, radius, radiusz ) ) {
8736 Creature *tmp_critter = g->critter_at( loc );
8737 if( tmp_critter != nullptr ) {
8738 creatures.push_back( tmp_critter );
8739 }
8740
8741 }
8742 return creatures;
8743}

References center, g, and points_in_radius().

◆ get_dir_circle()

std::vector< tripoint > map::get_dir_circle ( const tripoint f,
const tripoint t 
) const

Calculate next search points surrounding the current position.

Points closer to the target come first. This method leads to straighter lines and prevents weird looking movements away from the target.

Definition at line 6573 of file map.cpp.

6574{
6575 std::vector<tripoint> circle;
6576 circle.resize( 8 );
6577
6578 // The line below can be crazy expensive - we only take the FIRST point of it
6579 const std::vector<tripoint> line = line_to( f, t, 0, 0 );
6580 const std::vector<tripoint> spiral = closest_points_first( f, 1 );
6581 const std::vector<int> pos_index {1, 2, 4, 6, 8, 7, 5, 3};
6582
6583 // All possible constellations (closest_points_first goes clockwise)
6584 // 753 531 312 124 246 468 687 875
6585 // 8 1 7 2 5 4 3 6 1 8 2 7 4 5 6 3
6586 // 642 864 786 578 357 135 213 421
6587
6588 size_t pos_offset = 0;
6589 for( size_t i = 1; i < spiral.size(); i++ ) {
6590 if( spiral[i] == line[0] ) {
6591 pos_offset = i - 1;
6592 break;
6593 }
6594 }
6595
6596 for( size_t i = 1; i < spiral.size(); i++ ) {
6597 if( pos_offset >= pos_index.size() ) {
6598 pos_offset = 0;
6599 }
6600
6601 circle[pos_index[pos_offset++] - 1] = spiral[i];
6602 }
6603
6604 return circle;
6605}
void circle(map *m, const ter_id &type, double x, double y, double rad)
Definition: mapgen.cpp:6502

References circle(), closest_points_first(), line(), and line_to().

Referenced by npc::move_to().

◆ get_field() [1/2]

field & map::get_field ( const tripoint p)
private

Definition at line 8479 of file map.cpp.

8480{
8481 return field_at( p );
8482}

References field_at().

◆ get_field() [2/2]

field_entry * map::get_field ( const tripoint p,
const field_type_id type 
)

◆ get_field_age()

time_duration map::get_field_age ( const tripoint p,
const field_type_id type 
) const

Get the age of a field entry (field_entry::age), if there is no field of that type, returns -1_turns.

Definition at line 5373 of file map.cpp.

5374{
5375 auto field_ptr = field_at( p ).find_field( type );
5376 return field_ptr == nullptr ? -1_turns : field_ptr->get_field_age();
5377}

References field_at(), field::find_field(), field_entry::get_field_age(), and type.

Referenced by game::grabbed_furn_move(), try_fuel_fire(), and game::walk_move().

◆ get_field_intensity()

int map::get_field_intensity ( const tripoint p,
const field_type_id type 
) const

Get the intensity of a field entry (field_entry::intensity), if there is no field of that type, returns 0.

Definition at line 5379 of file map.cpp.

5380{
5381 auto field_ptr = field_at( p ).find_field( type );
5382 return ( field_ptr == nullptr ? 0 : field_ptr->get_field_intensity() );
5383}

References field_at(), field::find_field(), and type.

Referenced by Character::base_comfort_value(), game::grabbed_furn_move(), is_flammable(), propagate_field(), fungal_effects::spread_fungus_one_tile(), and game::walk_move().

◆ get_furn_field_locations()

const std::vector< tripoint > & map::get_furn_field_locations ( ) const

Definition at line 7759 of file map.cpp.

7760{
7761 return field_furn_locs;
7762}

References field_furn_locs.

Referenced by game::do_turn().

◆ get_furn_transforms_into()

furn_id map::get_furn_transforms_into ( const tripoint p) const

Definition at line 1612 of file map.cpp.

1613{
1614 return furn( p ).obj().transforms_into.id();
1615}
furn_str_id transforms_into
Definition: mapdata.h:499

References furn(), string_id< T >::id(), int_id< T >::obj(), and furn_t::transforms_into.

◆ get_harvest()

const harvest_id & map::get_harvest ( const tripoint p) const

Returns the full harvest list, for spawning.

Definition at line 1564 of file map.cpp.

1565{
1566 const auto furn_here = furn( pos );
1567 if( furn_here->examine != iexamine::none ) {
1568 // Note: if furniture can be examined, the terrain can NOT (until furniture is removed)
1569 if( furn_here->has_flag( TFLAG_HARVESTED ) ) {
1570 return harvest_id::NULL_ID();
1571 }
1572
1573 return furn_here->get_harvest();
1574 }
1575
1576 const auto ter_here = ter( pos );
1577 if( ter_here->has_flag( TFLAG_HARVESTED ) ) {
1578 return harvest_id::NULL_ID();
1579 }
1580
1581 return ter_here->get_harvest();
1582}
static const string_id< harvest_list > & NULL_ID()
Returns a null id whose string_id<T>::is_null() must always return true.
@ TFLAG_HARVESTED
Definition: mapdata.h:303

References furn(), iexamine::none(), string_id< harvest_list >::NULL_ID(), wrapped_vehicle::pos, ter(), and TFLAG_HARVESTED.

Referenced by harvest_common(), and is_harvestable().

◆ get_harvest_names()

const std::set< std::string > & map::get_harvest_names ( const tripoint p) const

Returns names of the items that would be dropped.

Definition at line 1584 of file map.cpp.

1585{
1586 static const std::set<std::string> null_harvest_names = {};
1587 const auto furn_here = furn( pos );
1588 if( furn_here->examine != iexamine::none ) {
1589 if( furn_here->has_flag( TFLAG_HARVESTED ) ) {
1590 return null_harvest_names;
1591 }
1592
1593 return furn_here->get_harvest_names();
1594 }
1595
1596 const auto ter_here = ter( pos );
1597 if( ter_here->has_flag( TFLAG_HARVESTED ) ) {
1598 return null_harvest_names;
1599 }
1600
1601 return ter_here->get_harvest_names();
1602}

References furn(), iexamine::none(), wrapped_vehicle::pos, ter(), and TFLAG_HARVESTED.

Referenced by npc::find_item().

◆ get_known_connections()

uint8_t map::get_known_connections ( const tripoint p,
int  connect_group,
const std::map< tripoint, ter_id > &  override = {} 
) const

Definition at line 1510 of file map.cpp.

1512{
1513 auto &ch = access_cache( p.z );
1514 uint8_t val = 0;
1515 std::function<bool( const tripoint & )> is_memorized;
1516#ifdef TILES
1517 if( use_tiles ) {
1518 is_memorized =
1519 [&]( const tripoint & q ) {
1520 return !g->u.get_memorized_tile( getabs( q ) ).tile.empty();
1521 };
1522 } else {
1523#endif
1524 is_memorized =
1525 [&]( const tripoint & q ) {
1526 return g->u.get_memorized_symbol( getabs( q ) );
1527 };
1528#ifdef TILES
1529 }
1530#endif
1531
1532 const bool overridden = override.find( p ) != override.end();
1533 const bool is_transparent = ch.transparency_cache[p.x][p.y] > LIGHT_TRANSPARENCY_SOLID;
1534
1535 // populate connection information
1536 for( int i = 0; i < 4; ++i ) {
1537 tripoint neighbour = p + offsets[i];
1538 if( !inbounds( neighbour ) ) {
1539 continue;
1540 }
1541 const auto neighbour_override = override.find( neighbour );
1542 const bool neighbour_overridden = neighbour_override != override.end();
1543 // if there's some non-memory terrain to show at the neighboring tile
1544 const bool may_connect = neighbour_overridden ||
1545 get_visibility( ch.visibility_cache[neighbour.x][neighbour.y],
1547 // or if an actual center tile is transparent or next to a memorized tile
1548 ( !overridden && ( is_transparent || is_memorized( neighbour ) ) );
1549 if( may_connect ) {
1550 const ter_t &neighbour_terrain = neighbour_overridden ?
1551 neighbour_override->second.obj() : ter( neighbour ).obj();
1552 if( neighbour_terrain.connects_to( connect_group ) ) {
1553 val += 1 << i;
1554 }
1555 }
1556 }
1557
1558 return val;
1559}
bool use_tiles
Use tiles for display.
bool is_transparent(const tripoint &p) const
Returns whether the tile at p is transparent(you can look past it).
Definition: lightmap.cpp:655
level_cache & access_cache(int zlev)
Definition: map.cpp:8745
static constexpr std::array< point, 4 > offsets
Definition: point.h:375
bool connects_to(int test_connect_group) const
Definition: mapdata.h:431

References access_cache(), map_data_common_t::connects_to(), g, get_visibility(), get_visibility_variables_cache(), getabs(), inbounds(), is_transparent(), LIGHT_TRANSPARENCY_SOLID, int_id< T >::obj(), offsets, ter(), use_tiles, VIS_CLEAR, tripoint::x, tripoint::y, and tripoint::z.

Referenced by determine_wall_corner().

◆ get_neighbors()

std::array< std::pair< tripoint, maptile >, 8 > map::get_neighbors ( const tripoint p)
private

Definition at line 190 of file map_field.cpp.

191{
192 // Find out which edges are in the bubble
193 // Where possible, do just one bounds check for all the neighbors
194 const bool west = p.x > 0;
195 const bool north = p.y > 0;
196 const bool east = p.x < SEEX * my_MAPSIZE - 1;
197 const bool south = p.y < SEEY * my_MAPSIZE - 1;
198 return std::array< std::pair<tripoint, maptile>, 8 > { {
199 maptile_has_bounds( p + eight_horizontal_neighbors[0], west &&north ),
201 maptile_has_bounds( p + eight_horizontal_neighbors[2], east &&north ),
204 maptile_has_bounds( p + eight_horizontal_neighbors[5], west &&south ),
206 maptile_has_bounds( p + eight_horizontal_neighbors[7], east &&south ),
207 }
208 };
209}
std::pair< tripoint, maptile > maptile_has_bounds(const tripoint &p, bool bounds_checked)
Definition: map_field.cpp:180
static const std::array< tripoint, 8 > eight_horizontal_neighbors
Definition: point.h:393

References eight_horizontal_neighbors, maptile_has_bounds(), my_MAPSIZE, SEEX, SEEY, tripoint::x, and tripoint::y.

Referenced by process_fields_in_submap(), and spread_gas().

◆ get_nonant() [1/2]

size_t map::get_nonant ( const point gridp) const
inlineprotected

Definition at line 1890 of file map.h.

1890 {
1891 return get_nonant( { gridp, abs_sub.z } );
1892 }

References abs_sub, get_nonant(), and tripoint::z.

◆ get_nonant() [2/2]

size_t map::get_nonant ( const tripoint gridp) const
protected

Get the index of a submap pointer in the grid given by grid coordinates.

The grid coordinates must be valid: 0 <= x < my_MAPSIZE, same for y. Version with z-levels checks for z between -OVERMAP_DEPTH and OVERMAP_HEIGHT

Definition at line 8335 of file map.cpp.

8336{
8337 // There used to be a bounds check here
8338 // But this function is called a lot, so push it up if needed
8339 if( zlevels ) {
8340 const int indexz = gridp.z + OVERMAP_HEIGHT; // Can't be lower than 0
8341 return indexz + ( gridp.x + gridp.y * my_MAPSIZE ) * OVERMAP_LAYERS;
8342 } else {
8343 return gridp.x + gridp.y * my_MAPSIZE;
8344 }
8345}

References my_MAPSIZE, OVERMAP_HEIGHT, OVERMAP_LAYERS, tripoint::x, tripoint::y, tripoint::z, and zlevels.

Referenced by copy_grid(), fake_map::fake_map(), generate(), get_nonant(), get_submap_at_grid(), loadn(), and saven().

◆ get_pathfinding_cache()

pathfinding_cache & map::get_pathfinding_cache ( int  zlev) const
private

Definition at line 8795 of file map.cpp.

8796{
8797 return *pathfinding_caches[zlev + OVERMAP_DEPTH];
8798}

References OVERMAP_DEPTH, and pathfinding_caches.

Referenced by get_pathfinding_cache_ref(), set_pathfinding_cache_dirty(), and update_pathfinding_cache().

◆ get_pathfinding_cache_ref()

const pathfinding_cache & map::get_pathfinding_cache_ref ( int  zlev) const

Definition at line 8807 of file map.cpp.

8808{
8809 if( !inbounds_z( zlev ) ) {
8810 debugmsg( "Tried to get pathfinding cache for out of bounds z-level %d", zlev );
8812 }
8813 auto &cache = get_pathfinding_cache( zlev );
8814 if( cache.dirty ) {
8816 }
8817
8818 return cache;
8819}
void update_pathfinding_cache(int zlev) const
Definition: map.cpp:8821
bool inbounds_z(const int z) const
Definition: map.h:1672
pathfinding_cache & get_pathfinding_cache(int zlev) const
Definition: map.cpp:8795

References debugmsg, get_pathfinding_cache(), inbounds_z(), OVERMAP_DEPTH, pathfinding_caches, and update_pathfinding_cache().

Referenced by route(), and vertical_move_destination().

◆ get_radiation()

int map::get_radiation ( const tripoint p) const

Definition at line 4034 of file map.cpp.

4035{
4036 if( !inbounds( p ) ) {
4037 return 0;
4038 }
4039
4040 point l;
4041 submap *const current_submap = get_submap_at( p, l );
4042
4043 return current_submap->get_radiation( l );
4044}

References submap::get_radiation(), get_submap_at(), and inbounds().

Referenced by computer_session::action_geiger(), computer_session::action_irradiator(), check_art_charge_req(), editmap::draw_main_ui_overlay(), rad_scorch(), and Character::suffer_from_radiation().

◆ get_roof()

ter_id map::get_roof ( const tripoint p,
bool  allow_air 
) const
private

Definition at line 3105 of file map.cpp.

3106{
3107 // This function should not be called from the 2D mode
3108 // Just use t_dirt instead
3109 assert( zlevels );
3110
3111 if( p.z <= -OVERMAP_DEPTH ) {
3112 // Could be magma/"void" instead
3113 return t_rock_floor;
3114 }
3115
3116 const auto &ter_there = ter( p ).obj();
3117 const auto &roof = ter_there.roof;
3118 if( !roof ) {
3119 // No roof
3120 if( !allow_air ) {
3121 // TODO: Biomes? By setting? Forbid and treat as bug?
3122 if( p.z < 0 ) {
3123 return t_rock_floor_no_roof;
3124 }
3125
3126 return t_dirt;
3127 }
3128
3129 return t_open_air;
3130 }
3131
3132 ter_id new_ter = roof.id();
3133 if( new_ter == t_null ) {
3134 debugmsg( "map::get_new_floor: %d,%d,%d has invalid roof type %s",
3135 p.x, p.y, p.z, roof.c_str() );
3136 return t_dirt;
3137 }
3138
3139 if( p.z == -1 && new_ter == t_rock_floor ) {
3140 // HACK: A hack to work around not having a "solid earth" tile
3141 new_ter = t_dirt;
3142 }
3143
3144 return new_ter;
3145}
static const ter_str_id t_rock_floor_no_roof("t_rock_floor_no_roof")

References debugmsg, int_id< T >::id(), int_id< T >::obj(), OVERMAP_DEPTH, ter_t::roof, t_dirt, t_null, t_open_air, t_rock_floor, t_rock_floor_no_roof, ter(), tripoint::x, tripoint::y, tripoint::z, and zlevels.

Referenced by bash_ter_furn(), and bash_ter_success().

◆ get_signage()

std::string map::get_signage ( const tripoint p) const

Definition at line 4000 of file map.cpp.

4001{
4002 if( !inbounds( p ) ) {
4003 return "";
4004 }
4005
4006 point l;
4007 submap *const current_submap = get_submap_at( p, l );
4008
4009 return current_submap->get_signage( l );
4010}
std::string get_signage(const point &p) const
Definition: submap.cpp:126

References submap::get_signage(), get_submap_at(), and inbounds().

Referenced by game::extended_description(), game::place_player(), game::print_terrain_info(), and iexamine::sign().

◆ get_submap_at() [1/4]

submap * map::get_submap_at ( const point p) const
inlineprivate

Definition at line 1862 of file map.h.

1862 {
1863 return get_submap_at( tripoint( p, abs_sub.z ) );
1864 }

References abs_sub, get_submap_at(), and tripoint::z.

◆ get_submap_at() [2/4]

submap * map::get_submap_at ( const point p,
point offset_p 
) const
inlineprivate

Definition at line 1871 of file map.h.

1871 {
1872 return get_submap_at( { p, abs_sub.z }, offset_p );
1873 }

References abs_sub, get_submap_at(), and tripoint::z.

◆ get_submap_at() [3/4]

◆ get_submap_at() [4/4]

submap * map::get_submap_at ( const tripoint p,
point offset_p 
) const
private

Get the submap pointer containing the specified position within the reality bubble.

The same as other get_submap_at, (p) must be valid (inbounds). Also writes the position within the submap to offset_p

Definition at line 8323 of file map.cpp.

8324{
8325 offset_p.x = p.x % SEEX;
8326 offset_p.y = p.y % SEEY;
8327 return get_submap_at( p );
8328}

References get_submap_at(), SEEX, SEEY, point::x, tripoint::x, point::y, and tripoint::y.

◆ get_submap_at_grid() [1/2]

◆ get_submap_at_grid() [2/2]

submap * map::get_submap_at_grid ( const tripoint gridp) const
private

Definition at line 8330 of file map.cpp.

8331{
8332 return getsubmap( get_nonant( gridp ) );
8333}

References get_nonant(), and getsubmap().

◆ get_submaps_with_active_items()

const std::set< tripoint > & map::get_submaps_with_active_items ( ) const
inline

Definition at line 2063 of file map.h.

2063 {
2065 }

References submaps_with_active_items.

◆ get_temperature()

int map::get_temperature ( const tripoint p) const

Definition at line 4071 of file map.cpp.

4072{
4073 if( !inbounds( p ) ) {
4074 return 0;
4075 }
4076
4077 return get_submap_at( p )->get_temperature();
4078}
int get_temperature() const
Definition: submap.h:194

References get_submap_at(), submap::get_temperature(), and inbounds().

Referenced by item::process_rot().

◆ get_ter_transforms_into()

ter_id map::get_ter_transforms_into ( const tripoint p) const

Definition at line 1607 of file map.cpp.

1608{
1609 return ter( p ).obj().transforms_into.id();
1610}
ter_str_id transforms_into
Definition: mapdata.h:466

References string_id< T >::id(), int_id< T >::obj(), ter(), and ter_t::transforms_into.

Referenced by iexamine::harvest_ter(), iexamine::harvest_ter_nectar(), and iexamine::tree_hickory().

◆ get_vehicle_zones()

std::vector< zone_data * > map::get_vehicle_zones ( int  zlev)

Definition at line 939 of file map.cpp.

940{
941 std::vector<zone_data *> veh_zones;
942 bool rebuild = false;
943 for( auto veh : get_cache( zlev ).zone_vehicles ) {
944 if( veh->refresh_zones() ) {
945 rebuild = true;
946 }
947 for( auto &zone : veh->loot_zones ) {
948 veh_zones.emplace_back( &zone.second );
949 }
950 }
951 if( rebuild ) {
953 }
954 return veh_zones;
955}
static zone_manager & get_manager()
Definition: clzones.cpp:126
void cache_vzones()
Definition: clzones.cpp:624

References zone_manager::cache_vzones(), get_cache(), and zone_manager::get_manager().

Referenced by zone_manager::cache_vzones(), zone_manager::get_bottom_zone(), zone_manager::get_zone_at(), and zone_manager::get_zones().

◆ get_vehicles() [1/2]

◆ get_vehicles() [2/2]

VehicleList map::get_vehicles ( const tripoint start,
const tripoint end 
)

Definition at line 980 of file map.cpp.

981{
982 const int chunk_sx = std::max( 0, ( start.x / SEEX ) - 1 );
983 const int chunk_ex = std::min( my_MAPSIZE - 1, ( end.x / SEEX ) + 1 );
984 const int chunk_sy = std::max( 0, ( start.y / SEEY ) - 1 );
985 const int chunk_ey = std::min( my_MAPSIZE - 1, ( end.y / SEEY ) + 1 );
986 const int chunk_sz = start.z;
987 const int chunk_ez = end.z;
988 VehicleList vehs;
989
990 for( int cx = chunk_sx; cx <= chunk_ex; ++cx ) {
991 for( int cy = chunk_sy; cy <= chunk_ey; ++cy ) {
992 for( int cz = chunk_sz; cz <= chunk_ez; ++cz ) {
993 submap *current_submap = get_submap_at_grid( { cx, cy, cz } );
994 for( const auto &elem : current_submap->vehicles ) {
995 // Ensure the vehicle z-position is correct
996 elem->sm_pos.z = cz;
998 w.v = elem.get();
999 w.pos = w.v->global_pos3();
1000 vehs.push_back( w );
1001 }
1002 }
1003 }
1004 }
1005
1006 return vehs;
1007}
tripoint pos
Definition: map.h:81
vehicle * v
Definition: map.h:82

References get_submap_at_grid(), vehicle::global_pos3(), my_MAPSIZE, wrapped_vehicle::pos, SEEX, SEEY, wrapped_vehicle::v, submap::vehicles, tripoint::x, tripoint::y, and tripoint::z.

◆ get_visibility()

visibility_type map::get_visibility ( lit_level  ll,
const visibility_variables cache 
) const

Definition at line 5662 of file map.cpp.

5664{
5665 switch( ll ) {
5666 case lit_level::DARK:
5667 // can't see this square at all
5668 if( cache.u_is_boomered ) {
5669 return VIS_BOOMER_DARK;
5670 } else {
5671 return VIS_DARK;
5672 }
5674 // can only tell that this square is bright
5675 if( cache.u_is_boomered ) {
5676 return VIS_BOOMER;
5677 } else {
5678 return VIS_LIT;
5679 }
5680
5681 case lit_level::LOW:
5682 // low light, square visible in monochrome
5683 case lit_level::LIT:
5684 // normal light
5685 case lit_level::BRIGHT:
5686 // bright light
5687 return VIS_CLEAR;
5688 case lit_level::BLANK:
5690 return VIS_HIDDEN;
5691 }
5692 return VIS_HIDDEN;
5693}
bool u_is_boomered
Definition: map.h:124

References BLANK, BRIGHT, BRIGHT_ONLY, DARK, LIT, LOW, MEMORIZED, visibility_variables::u_is_boomered, VIS_BOOMER, VIS_BOOMER_DARK, VIS_CLEAR, VIS_DARK, VIS_HIDDEN, and VIS_LIT.

Referenced by draw(), game::draw_look_around_cursor(), generate_weather_anim_frame(), get_known_connections(), and game::print_all_tile_info().

◆ get_visibility_variables_cache()

const visibility_variables & map::get_visibility_variables_cache ( ) const

Definition at line 5657 of file map.cpp.

5658{
5660}
visibility_variables visibility_variables_cache
Definition: map.h:2042

References visibility_variables_cache.

Referenced by draw(), generate_weather_anim_frame(), get_known_connections(), game::look_around(), live_view::show(), and editmap::update_view_with_help().

◆ get_wind_blockers()

std::tuple< maptile, maptile, maptile > map::get_wind_blockers ( const int &  winddirection,
const tripoint pos 
)

Definition at line 1894 of file map_field.cpp.

1896{
1897 static const std::array<std::pair<int, std::tuple< point, point, point >>, 9> outputs = {{
1898 { 330, std::make_tuple( point_east, point_north_east, point_south_east ) },
1899 { 301, std::make_tuple( point_south_east, point_east, point_south ) },
1900 { 240, std::make_tuple( point_south, point_south_west, point_south_east ) },
1901 { 211, std::make_tuple( point_south_west, point_west, point_south ) },
1902 { 150, std::make_tuple( point_west, point_north_west, point_south_west ) },
1903 { 121, std::make_tuple( point_north_west, point_north, point_west ) },
1904 { 60, std::make_tuple( point_north, point_north_west, point_north_east ) },
1905 { 31, std::make_tuple( point_north_east, point_east, point_north ) },
1906 { 0, std::make_tuple( point_east, point_north_east, point_south_east ) }
1907 }
1908 };
1909
1910 tripoint removepoint;
1911 tripoint removepoint2;
1912 tripoint removepoint3;
1913 for( const std::pair<int, std::tuple< point, point, point >> &val : outputs ) {
1914 if( winddirection >= val.first ) {
1915 removepoint = pos + std::get<0>( val.second );
1916 removepoint2 = pos + std::get<1>( val.second );
1917 removepoint3 = pos + std::get<2>( val.second );
1918 break;
1919 }
1920 }
1921
1922 const maptile remove_tile = maptile_at( removepoint );
1923 const maptile remove_tile2 = maptile_at( removepoint2 );
1924 const maptile remove_tile3 = maptile_at( removepoint3 );
1925 return std::make_tuple( remove_tile, remove_tile2, remove_tile3 );
1926}

References maptile_at(), point_east, point_north, point_north_east, point_north_west, point_south, point_south_east, point_south_west, and point_west.

Referenced by spread_gas().

◆ getabs() [1/2]

point map::getabs ( const point p) const
inline

Definition at line 1657 of file map.h.

1657 {
1658 return getabs( tripoint( p, abs_sub.z ) ).xy();
1659 }

References abs_sub, getabs(), tripoint::xy(), and tripoint::z.

◆ getabs() [2/2]

tripoint map::getabs ( const tripoint p) const

Translates local (to this map) coordinates of a square to global absolute coordinates.

Coordinates is in the system that is used by the ter/furn/i_at functions. Output is in the same scale, but in global system.

Definition at line 8273 of file map.cpp.

8274{
8275 return sm_to_ms_copy( abs_sub.xy() ) + p;
8276}

References abs_sub, sm_to_ms_copy(), and tripoint::xy().

Referenced by activity_on_turn_move_loot(), add_basecamp_storage_to_loot_zone_list(), add_item(), Character::add_known_trap(), jmapgen_zone::apply(), are_requirements_nearby(), game::autopilot_vehicles(), talk_function::basecamp_mission(), bash_ter_furn(), iexamine::bulletin_board(), butcher_corpse_activity(), can_do_activity_there(), iexamine::cardreader(), vehicle::autodrive_controller::check_drivable(), game::check_near_zone(), game::check_zone(), chop_plank_activity(), chop_tree_activity(), complete_construction(), construction_activity(), game::control_vehicle(), activity_handlers::repair_activity_hack::anonymous_namespace{activity_handlers.cpp}::discharge_real_power_source(), npc::do_pulp(), construct::done_digormine_stair(), construct::done_mine_upstair(), draw_maptile(), editmap::edit_mapgen(), iexamine::elevator(), fill_funnels(), find_auto_consume(), game::find_or_make_stairs(), find_refuel_spot_zone(), find_valid_teleporters_omt(), activity_handlers::forage_finish(), inventory::form_from_map(), furn_set(), generic_multi_activity_check_requirement(), generic_multi_activity_do(), generic_multi_activity_handler(), generic_multi_activity_locations(), activity_handlers::repair_activity_hack::anonymous_namespace{activity_handlers.cpp}::get_fake_tool(), get_known_connections(), zone_manager::get_point_set_loot(), getabs(), Character::global_square_location(), npc::go_to_omt_destination(), good_fishing_spot(), game::grabbed_furn_move(), grow_plant(), npc::guard_current_pos(), npc::handle_sound(), Character::knows_trap(), mine_activity(), npc::move(), perform_zone_activity_turn(), place_construction(), game::place_player(), basecamp::place_results(), game::place_vehicle_nearby(), iexamine::plant_seed(), game::pre_print_all_tile_info(), sounds::process_sounds(), plot_options::query_seed(), npc::reach_omt_destination(), remove_submap_turrets(), requirements_map(), zone_manager::rotate_zones(), conditional_t< T >::set_is_outside(), target_ui::set_last_target(), shoot(), iexamine::shrub_wildveggies(), smash(), spawn_monsters_submap_group(), debug_menu::spawn_nested_mapgen(), spread_gas(), ter_set(), tidy_activity(), vehicle::total_wind_epower_w(), translate_radius(), iexamine::trap(), update_suspension_cache(), use_charges_from_furn(), iexamine::use_furn_fake_item(), basecamp::validate_sort_points(), vehicle_activity(), vertical_move_destination(), iuse::weather_tool(), npc::worker_downtime(), and game::zones_manager().

◆ getlocal() [1/2]

point map::getlocal ( const point p) const
inline

Definition at line 1664 of file map.h.

1664 {
1665 return getlocal( tripoint( p, abs_sub.z ) ).xy();
1666 }

References abs_sub, getlocal(), tripoint::xy(), and tripoint::z.

◆ getlocal() [2/2]

tripoint map::getlocal ( const tripoint p) const

Inverse of getabs.

Definition at line 8278 of file map.cpp.

8279{
8280 return p - sm_to_ms_copy( abs_sub.xy() );
8281}

References abs_sub, sm_to_ms_copy(), and tripoint::xy().

Referenced by basecamp::abandon_camp(), activity_on_turn_move_loot(), zone_manager::add(), add_basecamp_storage_to_loot_zone_list(), grid_furn_transform_queue::apply(), talk_function::basecamp_mission(), activity_handlers::build_do_turn(), can_do_activity_there(), Character::check_outbounds_activity(), activity_handlers::chop_logs_finish(), activity_handlers::chop_planks_finish(), activity_handlers::chop_tree_do_turn(), activity_handlers::chop_tree_finish(), activity_handlers::churn_finish(), cleanup_tiles(), complete_construction(), veh_interact::complete_vehicle(), vehicle::autodrive_controller::compute_obstacles(), basecamp_action_components::consume_components(), deregister_vehicle_zone(), basecamp::distribute_food(), construct::done_digormine_stair(), construct::done_mine_upstair(), editmap::edit_mapgen(), npc::execute_action(), fetch_activity(), find_auto_consume(), game::find_or_make_stairs(), find_refuel_spot_zone(), activity_handlers::forage_finish(), basecamp::form_crafting_inventory(), inventory::form_from_zone(), generic_multi_activity_check_requirement(), generic_multi_activity_handler(), generic_multi_activity_locations(), item::get_cable_target(), zone_manager::get_point_set_loot(), getlocal(), npc::go_to_omt_destination(), npc::good_escape_direction(), Character::has_destination_activity(), activity_handlers::jackhammer_do_turn(), activity_handlers::jackhammer_finish(), activity_handlers::milk_finish(), npc::move(), npc::move_to(), map_cursor::operator tripoint(), perform_zone_activity_turn(), activity_handlers::pickaxe_do_turn(), activity_handlers::pickaxe_finish(), teleporter_list::place_avatar_overmap(), basecamp::place_results(), game::place_vehicle_nearby(), activity_handlers::plant_seed_finish(), vehicle_part::properties_to_item(), activity_handlers::pulp_do_turn(), plot_options::query_seed(), npc::reach_omt_destination(), target_ui::recalc_aim_turning_penalty(), npc::regen_ai_cache(), requirements_map(), zone_manager::revert_vzones(), rotate(), zone_manager::rotate_zones(), activity_handlers::shear_finish(), debug_menu::spawn_nested_mapgen(), tidy_activity(), activity_handlers::travel_do_turn(), target_ui::try_reacquire_target(), update_suspension_cache(), basecamp::validate_sort_points(), activity_handlers::vehicle_finish(), vertical_move_destination(), npc::worker_downtime(), and game::zones_manager().

◆ getmapsize()

int map::getmapsize ( ) const
inline

Definition at line 1681 of file map.h.

1681 {
1682 return my_MAPSIZE;
1683 }

References my_MAPSIZE.

Referenced by distribution_grid_tracker::load(), editmap::mapgen_preview(), and points_in_range().

◆ getsubmap()

submap * map::getsubmap ( size_t  grididx) const
private

Get the submap pointer with given index in grid, the index must be valid!

Definition at line 8293 of file map.cpp.

8294{
8295 if( grididx >= grid.size() ) {
8296 debugmsg( "Tried to access invalid grid index %d. Grid size: %d", grididx, grid.size() );
8297 return nullptr;
8298 }
8299 return grid[grididx];
8300}

References debugmsg, and grid.

Referenced by generate(), get_submap_at_grid(), and saven().

◆ graffiti_at()

const std::string & map::graffiti_at ( const tripoint p) const

Definition at line 7835 of file map.cpp.

7836{
7837 if( !inbounds( p ) ) {
7838 static const std::string empty_string;
7839 return empty_string;
7840 }
7841 point l;
7842 submap *const current_submap = get_submap_at( p, l );
7843 return current_submap->get_graffiti( l );
7844}
const std::string & get_graffiti(const point &p) const
Definition: submap.cpp:88

References submap::get_graffiti(), get_submap_at(), and inbounds().

Referenced by advanced_inv_area::init(), game::place_player(), game::print_graffiti_info(), and editmap::update_view_with_help().

◆ grow_plant()

void map::grow_plant ( const tripoint p)
protected

Try to grow a harvestable plant to the next stage(s).

Definition at line 7164 of file map.cpp.

7165{
7166 const auto &furn = this->furn( p ).obj();
7167 if( !furn.has_flag( "PLANT" ) ) {
7168 return;
7169 }
7170 // Can't use item_stack::only_item() since there might be fertilizer
7171 map_stack items = i_at( p );
7172 map_stack::iterator seed = std::find_if( items.begin(), items.end(), []( const item & it ) {
7173 return it.is_seed();
7174 } );
7175
7176 if( seed == items.end() ) {
7177 // No seed there anymore, we don't know what kind of plant it was.
7178 // TODO: Fix point types
7179 const oter_id ot = overmap_buffer.ter( project_to<coords::omt>( tripoint_abs_ms( getabs( p ) ) ) );
7180 dbg( DL::Error ) << "a planted item at " << p
7181 << " (within overmap terrain " << ot.id().str() << ") has no seed data";
7182 i_clear( p );
7183 furn_set( p, f_null );
7184 return;
7185 }
7186 const time_duration plantEpoch = seed->get_plant_epoch();
7187 if( seed->age() >= plantEpoch * furn.plant->growth_multiplier &&
7188 !furn.has_flag( "GROWTH_HARVEST" ) ) {
7189 if( seed->age() < plantEpoch * 2 ) {
7190 if( has_flag_furn( "GROWTH_SEEDLING", p ) ) {
7191 return;
7192 }
7193
7194 // Remove fertilizer if any
7195 map_stack::iterator fertilizer = std::find_if( items.begin(), items.end(), []( const item & it ) {
7196 return it.has_flag( "FERTILIZER" );
7197 } );
7198 if( fertilizer != items.end() ) {
7199 items.erase( fertilizer );
7200 }
7201
7202 rotten_item_spawn( *seed, p );
7203 furn_set( p, furn_str_id( furn.plant->transform ) );
7204 } else if( seed->age() < plantEpoch * 3 * furn.plant->growth_multiplier ) {
7205 if( has_flag_furn( "GROWTH_MATURE", p ) ) {
7206 return;
7207 }
7208
7209 // Remove fertilizer if any
7210 map_stack::iterator fertilizer = std::find_if( items.begin(), items.end(), []( const item & it ) {
7211 return it.has_flag( "FERTILIZER" );
7212 } );
7213 if( fertilizer != items.end() ) {
7214 items.erase( fertilizer );
7215 }
7216
7217 rotten_item_spawn( *seed, p );
7218 //You've skipped the seedling stage so roll monsters twice
7219 if( !has_flag_furn( "GROWTH_SEEDLING", p ) ) {
7220 rotten_item_spawn( *seed, p );
7221 }
7222 furn_set( p, furn_str_id( furn.plant->transform ) );
7223 } else {
7224 //You've skipped two stages so roll monsters two times
7225 if( has_flag_furn( "GROWTH_SEEDLING", p ) ) {
7226 rotten_item_spawn( *seed, p );
7227 rotten_item_spawn( *seed, p );
7228 //One stage change
7229 } else if( has_flag_furn( "GROWTH_MATURE", p ) ) {
7230 rotten_item_spawn( *seed, p );
7231 //Goes from seed to harvest in one check
7232 } else {
7233 rotten_item_spawn( *seed, p );
7234 rotten_item_spawn( *seed, p );
7235 rotten_item_spawn( *seed, p );
7236 }
7237 furn_set( p, furn_str_id( furn.plant->transform ) );
7238 }
7239 }
7240}
iterator erase(const_iterator it) override
Definition: map.cpp:152
void rotten_item_spawn(const item &item, const tripoint &p)
Checks to see if the item that is rotting away generates a creature when it does.
Definition: map.cpp:7116
string_id< furn_t > furn_str_id
Definition: type_id.h:65

References item_stack::begin(), dbg, item_stack::end(), map_stack::erase(), Error, f_null, furn(), furn_set(), getabs(), has_flag_furn(), i_at(), i_clear(), int_id< T >::id(), int_id< T >::obj(), overmap_buffer, rotten_item_spawn(), iuse::seed(), string_id< T >::str(), and overmapbuffer::ter().

Referenced by actualize().

◆ has_adjacent_furniture_with()

bool map::has_adjacent_furniture_with ( const tripoint p,
const std::function< bool(const furn_t &)> &  filter 
)

Returns true if there is furniture for which filter returns true in a 1 tile radius of p.

Pass return_true<furn_t> to detect all adjacent furniture.

Parameters
pthe location to check at
filterwhat to filter the furniture by.

Definition at line 2752 of file map.cpp.

2754{
2755 for( const tripoint &adj : points_in_radius( p, 1 ) ) {
2756 if( has_furn( adj ) && filter( furn( adj ).obj() ) ) {
2757 return true;
2758 }
2759 }
2760
2761 return false;
2762}

References furn(), has_furn(), and points_in_radius().

◆ has_flag() [1/4]

bool map::has_flag ( const std::string &  flag,
const point p 
) const
inline

Definition at line 964 of file map.h.

964 {
965 return has_flag( flag, tripoint( p, abs_sub.z ) );
966 }

References abs_sub, has_flag(), and tripoint::z.

◆ has_flag() [2/4]

bool map::has_flag ( const std::string &  flag,
const tripoint p 
) const

Definition at line 2293 of file map.cpp.

2294{
2295 return has_flag_ter_or_furn( flag, p ); // Does bound checking
2296}

References has_flag_ter_or_furn().

Referenced by accessible_items(), Character::activate_bionic(), add_item(), add_item_or_charges(), npc::assess_danger(), bash(), bash_ter_furn(), bash_ter_success(), start_location::burn(), activity_handlers::burrow_finish(), game::butcher(), can_do_activity_there(), can_examine_at(), can_move_vertical_at(), can_put_items_ter_furn(), monster::can_reach_to(), iexamine::chainfence(), construct::check_empty(), vehicle::check_falling_or_floating(), construct::check_support(), chop_tree_activity(), climb_difficulty(), close_door(), doors::close_door(), collapse_at(), collapse_check(), consider_butchery(), iexamine::curtains(), displace_water(), dont_draw_lower_floor(), iexamine::door_peephole(), draw_lab(), drop_everything(), drop_or_embed_projectile(), iexamine::elevator(), explosion_handler::emp_blast(), game::examine(), computer_session::failure_shutdown(), features(), find_closest_stair(), find_furnitures_or_vparts_with_flag_in_radius(), game::find_or_make_stairs(), flammable_items_at(), game::fling_creature(), game::forced_door_closing(), generic_multi_activity_do(), game::get_dangerous_tile(), get_fire_fuel_string(), game::get_fishable_locations(), overmap_ui::get_overmap_path_to(), game::grabbed_furn_move(), has_flag(), has_nearby_chair(), has_nearby_table(), haul(), hit_with_fire(), in_spell_aoe(), vehicle::interact_with(), is_divable(), game::is_empty(), is_flammable(), is_water_shallow_current(), game::knockback(), mine_activity(), mop_spills(), monster::move(), avatar_action::move(), npc::move_to(), move_vehicle(), game::moving_vehicle_dismount(), MapExtras::mx_minefield(), item::on_drop(), open(), open_door(), vehicle::part_collision(), activity_handlers::pickaxe_finish(), game::place_player(), game::print_fields_info(), game::print_items_info(), item::process_extinguish(), process_fields_in_submap(), item::process_litcig(), spell_effect::projectile_attack(), propagate_field(), propagate_suspension_check(), avatar_action::ramp_move(), rate_location(), route(), area_expander::run(), Character::run_cost(), conditional_t< T >::set_is_outside(), vehicle::shift_zlevel(), shoot(), spawn_an_item(), spawn_items(), spell_effect::spell_effect_cone(), fungal_effects::spread_fungus(), fungal_effects::spread_fungus_one_tile(), monster::stumble(), Character::suffer_from_other_mutations(), avatar_action::swim(), test_passable(), game::update_stair_monsters(), editmap::update_view_with_help(), place_trap_actor::use(), deploy_tent_actor::use(), use_charges_from_furn(), game::use_computer(), game::vertical_move(), vertical_move_destination(), game::walk_move(), water_from(), and npc::worker_downtime().

◆ has_flag() [3/4]

bool map::has_flag ( ter_bitflags  flag,
const point p 
) const
inline

Definition at line 999 of file map.h.

999 {
1000 return has_flag( flag, tripoint( p, abs_sub.z ) );
1001 }

References abs_sub, has_flag(), and tripoint::z.

◆ has_flag() [4/4]

bool map::has_flag ( ter_bitflags  flag,
const tripoint p 
) const

Definition at line 2336 of file map.cpp.

2337{
2338 return has_flag_ter_or_furn( flag, p ); // Does bound checking
2339}

References has_flag_ter_or_furn().

◆ has_flag_furn() [1/4]

bool map::has_flag_furn ( const std::string &  flag,
const point p 
) const
inline

Definition at line 984 of file map.h.

984 {
985 return has_flag_furn( flag, tripoint( p, abs_sub.z ) );
986 }

References abs_sub, has_flag_furn(), and tripoint::z.

◆ has_flag_furn() [2/4]

◆ has_flag_furn() [3/4]

bool map::has_flag_furn ( ter_bitflags  flag,
const point p 
) const
inline

Definition at line 1009 of file map.h.

1009 {
1010 return has_flag_furn( flag, tripoint( p, abs_sub.z ) );
1011 }

References abs_sub, has_flag_furn(), and tripoint::z.

◆ has_flag_furn() [4/4]

bool map::has_flag_furn ( ter_bitflags  flag,
const tripoint p 
) const

Definition at line 2346 of file map.cpp.

2347{
2348 return furn( p ).obj().has_flag( flag );
2349}

References furn(), map_data_common_t::has_flag(), and int_id< T >::obj().

◆ has_flag_furn_or_vpart()

bool map::has_flag_furn_or_vpart ( const std::string &  flag,
const tripoint p 
) const

Definition at line 2357 of file map.cpp.

2358{
2359 return has_flag_furn( flag, p ) || has_flag_vpart( flag, p );
2360}
bool has_flag_vpart(const std::string &flag, const tripoint &p) const
Definition: map.cpp:2351

References has_flag_furn(), and has_flag_vpart().

Referenced by find_furnitures_or_vparts_with_flag_in_radius(), activity_handlers::operation_do_turn(), and operator_present().

◆ has_flag_ter() [1/4]

bool map::has_flag_ter ( const std::string &  flag,
const point p 
) const
inline

Definition at line 979 of file map.h.

979 {
980 return has_flag_ter( flag, tripoint( p, abs_sub.z ) );
981 }

References abs_sub, has_flag_ter(), and tripoint::z.

◆ has_flag_ter() [2/4]

◆ has_flag_ter() [3/4]

bool map::has_flag_ter ( ter_bitflags  flag,
const point p 
) const
inline

Definition at line 1004 of file map.h.

1004 {
1005 return has_flag_ter( flag, tripoint( p, abs_sub.z ) );
1006 }

References abs_sub, has_flag_ter(), and tripoint::z.

◆ has_flag_ter() [4/4]

bool map::has_flag_ter ( ter_bitflags  flag,
const tripoint p 
) const

Definition at line 2341 of file map.cpp.

2342{
2343 return ter( p ).obj().has_flag( flag );
2344}

References map_data_common_t::has_flag(), int_id< T >::obj(), and ter().

◆ has_flag_ter_or_furn() [1/4]

bool map::has_flag_ter_or_furn ( const std::string &  flag,
const point p 
) const
inline

Definition at line 993 of file map.h.

993 {
994 return has_flag_ter_or_furn( flag, tripoint( p, abs_sub.z ) );
995 }

References abs_sub, has_flag_ter_or_furn(), and tripoint::z.

◆ has_flag_ter_or_furn() [2/4]

◆ has_flag_ter_or_furn() [3/4]

bool map::has_flag_ter_or_furn ( ter_bitflags  flag,
const point p 
) const
inline

Definition at line 1014 of file map.h.

1014 {
1015 return has_flag_ter_or_furn( flag, tripoint( p, abs_sub.z ) );
1016 }

References abs_sub, has_flag_ter_or_furn(), and tripoint::z.

◆ has_flag_ter_or_furn() [4/4]

bool map::has_flag_ter_or_furn ( ter_bitflags  flag,
const tripoint p 
) const

Definition at line 2362 of file map.cpp.

2363{
2364 if( !inbounds( p ) ) {
2365 return false;
2366 }
2367
2368 point l;
2369 submap *const current_submap = get_submap_at( p, l );
2370
2371 return current_submap && //FIXME: can be null during mapgen
2372 ( current_submap->get_ter( l ).obj().has_flag( flag ) ||
2373 current_submap->get_furn( l ).obj().has_flag( flag ) );
2374}

References submap::get_furn(), get_submap_at(), submap::get_ter(), map_data_common_t::has_flag(), inbounds(), and int_id< T >::obj().

◆ has_flag_vpart()

bool map::has_flag_vpart ( const std::string &  flag,
const tripoint p 
) const

Definition at line 2351 of file map.cpp.

2352{
2353 const optional_vpart_position vp = veh_at( p );
2354 return static_cast<bool>( vp.part_with_feature( flag, true ) );
2355}

References optional_vpart_position::part_with_feature(), and veh_at().

Referenced by has_flag_furn_or_vpart().

◆ has_floor()

bool map::has_floor ( const tripoint p) const

◆ has_floor_or_support()

bool map::has_floor_or_support ( const tripoint p) const

Definition at line 2039 of file map.cpp.

2040{
2041 const tripoint below( p.xy(), p.z - 1 );
2042 return !valid_move( p, below, false, true );
2043}

References valid_move(), tripoint::xy(), and tripoint::z.

Referenced by monster::move(), game::print_terrain_info(), avatar_action::ramp_move(), reachable_flood_steps(), smash(), and game::vertical_move().

◆ has_furn() [1/2]

bool map::has_furn ( const point p) const
inline

Definition at line 849 of file map.h.

849 {
850 return has_furn( tripoint( p, abs_sub.z ) );
851 }

References abs_sub, has_furn(), and tripoint::z.

◆ has_furn() [2/2]

◆ has_graffiti_at()

bool map::has_graffiti_at ( const tripoint p) const

Definition at line 7846 of file map.cpp.

7847{
7848 if( !inbounds( p ) ) {
7849 return false;
7850 }
7851 point l;
7852 submap *const current_submap = get_submap_at( p, l );
7853 return current_submap->has_graffiti( l );
7854}
bool has_graffiti(const point &p) const
Definition: submap.cpp:83

References get_submap_at(), submap::has_graffiti(), and inbounds().

Referenced by editmap::draw_main_ui_overlay(), advanced_inv_area::init(), game::place_player(), game::print_graffiti_info(), and editmap::update_view_with_help().

◆ has_items()

bool map::has_items ( const tripoint p) const

Checks for existence of items.

Faster than i_at(p).empty

Definition at line 4771 of file map.cpp.

4772{
4773 if( !inbounds( p ) ) {
4774 return false;
4775 }
4776
4777 point l;
4778 submap *const current_submap = get_submap_at( p, l );
4779
4780 return !current_submap->get_items( l ).empty();
4781}

References submap::get_items(), get_submap_at(), and inbounds().

Referenced by Character::activate_bionic(), bash_items(), can_do_activity_there(), can_examine_at(), can_pickup_at(), drop_furniture(), drop_items(), flammable_items_at(), inventory::form_from_map(), generate_lightmap(), has_clear_path_to_pickup_items(), haul(), iuse::note_bionics(), npc::pick_up_item(), game::place_player(), sees_some_items(), and smash_items().

◆ has_nearby_chair()

bool map::has_nearby_chair ( const tripoint p,
int  radius = 1 
)

Check whether a chair or vehicle seat is nearby.

Definition at line 2791 of file map.cpp.

2792{
2793 for( const tripoint &pt : points_in_radius( p, radius ) ) {
2794 const optional_vpart_position vp = veh_at( pt );
2795 if( has_flag( "CAN_SIT", pt ) ) {
2796 return true;
2797 }
2798 if( vp && vp->vehicle().has_part( "SEAT" ) ) {
2799 return true;
2800 }
2801 }
2802 return false;
2803}

References has_flag(), points_in_radius(), and veh_at().

◆ has_nearby_fire()

bool map::has_nearby_fire ( const tripoint p,
int  radius = 1 
)

Definition at line 2764 of file map.cpp.

2765{
2766 for( const tripoint &pt : points_in_radius( p, radius ) ) {
2767 if( get_field( pt, fd_fire ) != nullptr ) {
2768 return true;
2769 }
2770 if( has_flag_ter_or_furn( "USABLE_FIRE", pt ) ) {
2771 return true;
2772 }
2773 }
2774 return false;
2775}

References fd_fire, get_field(), has_flag_ter_or_furn(), and points_in_radius().

Referenced by iexamine::fireplace(), and inventory::form_from_map().

◆ has_nearby_table()

bool map::has_nearby_table ( const tripoint p,
int  radius = 1 
)

Check whether a table/workbench/vehicle kitchen or other flat surface is nearby that could be used for crafting or eating.

Definition at line 2777 of file map.cpp.

2778{
2779 for( const tripoint &pt : points_in_radius( p, radius ) ) {
2780 const optional_vpart_position vp = veh_at( p );
2781 if( has_flag( "FLAT_SURF", pt ) ) {
2782 return true;
2783 }
2784 if( vp && ( vp->vehicle().has_part( "KITCHEN" ) || vp->vehicle().has_part( "FLAT_SURF" ) ) ) {
2785 return true;
2786 }
2787 }
2788 return false;
2789}

References has_flag(), points_in_radius(), and veh_at().

Referenced by can_do_activity_there(), and consider_butchery().

◆ has_zlevels()

◆ hit_with_acid()

bool map::hit_with_acid ( const tripoint p)

Definition at line 3830 of file map.cpp.

3831{
3832 if( passable( p ) ) {
3833 return false; // Didn't hit the tile!
3834 }
3835 const ter_id t = ter( p );
3836 if( t == t_wall_glass || t == t_wall_glass_alarm ||
3837 t == t_vat ) {
3838 ter_set( p, t_floor );
3839 } else if( t == t_door_c || t == t_door_locked || t == t_door_locked_peep ||
3840 t == t_door_locked_alarm ) {
3841 if( one_in( 3 ) ) {
3842 ter_set( p, t_door_b );
3843 }
3844 } else if( t == t_door_bar_c || t == t_door_bar_o || t == t_door_bar_locked || t == t_bars ||
3845 t == t_reb_cage ) {
3846 ter_set( p, t_floor );
3847 add_msg( m_warning, _( "The metal bars melt!" ) );
3848 } else if( t == t_door_b ) {
3849 if( one_in( 4 ) ) {
3850 ter_set( p, t_door_frame );
3851 } else {
3852 return false;
3853 }
3854 } else if( t == t_window || t == t_window_alarm || t == t_window_no_curtains ) {
3855 ter_set( p, t_window_empty );
3856 } else if( t == t_wax ) {
3857 ter_set( p, t_floor_wax );
3858 } else if( t == t_gas_pump || t == t_gas_pump_smashed ) {
3859 return false;
3860 } else if( t == t_card_science || t == t_card_military || t == t_card_industrial ) {
3862 }
3863 return true;
3864}
@ m_warning
Definition: enums.h:264
ter_id t_card_industrial
Definition: mapdata.cpp:722
ter_id t_floor_wax
Definition: mapdata.cpp:685
ter_id t_reb_cage
Definition: mapdata.cpp:654
ter_id t_card_military
Definition: mapdata.cpp:722
ter_id t_door_bar_locked
Definition: mapdata.cpp:663
ter_id t_window_alarm
Definition: mapdata.cpp:668
ter_id t_door_bar_o
Definition: mapdata.cpp:663
ter_id t_gas_pump
Definition: mapdata.cpp:698
ter_id t_wall_glass_alarm
Definition: mapdata.cpp:649
ter_id t_card_reader_broken
Definition: mapdata.cpp:722
ter_id t_gas_pump_smashed
Definition: mapdata.cpp:698
ter_id t_door_locked_peep
Definition: mapdata.cpp:657
ter_id t_door_bar_c
Definition: mapdata.cpp:663
ter_id t_door_frame
Definition: mapdata.cpp:658
ter_id t_vat
Definition: mapdata.cpp:710
ter_id t_window_no_curtains
Definition: mapdata.cpp:672
ter_id t_wax
Definition: mapdata.cpp:685
ter_id t_window_empty
Definition: mapdata.cpp:668
ter_id t_door_b
Definition: mapdata.cpp:656

References _, add_msg(), m_warning, one_in(), passable(), t_bars, t_card_industrial, t_card_military, t_card_reader_broken, t_card_science, t_door_b, t_door_bar_c, t_door_bar_locked, t_door_bar_o, t_door_c, t_door_frame, t_door_locked, t_door_locked_alarm, t_door_locked_peep, t_floor, t_floor_wax, t_gas_pump, t_gas_pump_smashed, t_reb_cage, t_vat, t_wall_glass, t_wall_glass_alarm, t_wax, t_window, t_window_alarm, t_window_empty, t_window_no_curtains, ter(), and ter_set().

◆ hit_with_fire()

bool map::hit_with_fire ( const tripoint p)

Definition at line 3867 of file map.cpp.

3868{
3869 if( passable( p ) ) {
3870 return false; // Didn't hit the tile!
3871 }
3872
3873 // non passable but flammable terrain, set it on fire
3874 if( has_flag( "FLAMMABLE", p ) || has_flag( "FLAMMABLE_ASH", p ) ) {
3875 add_field( p, fd_fire, 3 );
3876 }
3877 return true;
3878}

References add_field(), fd_fire, has_flag(), and passable().

Referenced by mattack::flame().

◆ hoist_submap_camp()

basecamp map::hoist_submap_camp ( const tripoint p)

Definition at line 5585 of file map.cpp.

5586{
5587 basecamp *pcamp = get_submap_at( p )->camp.get();
5588 return pcamp ? *pcamp : basecamp();
5589}
std::unique_ptr< basecamp > camp
Definition: submap.h:249

References submap::camp, and get_submap_at().

Referenced by game::validate_camps().

◆ i_at() [1/2]

map_stack map::i_at ( const point p)
inline

Definition at line 1240 of file map.h.

1240 {
1241 return i_at( tripoint( p, abs_sub.z ) );
1242 }

References abs_sub, i_at(), and tripoint::z.

◆ i_at() [2/2]

map_stack map::i_at ( const tripoint p)

Definition at line 4090 of file map.cpp.

4091{
4092 if( !inbounds( p ) ) {
4093 nulitems.clear();
4094 return map_stack{ &nulitems, p, this };
4095 }
4096
4097 point l;
4098 submap *const current_submap = get_submap_at( p, l );
4099
4100 return map_stack{ &current_submap->get_items( l ), p, this };
4101}
static cata::colony< item > nulitems
Definition: map.cpp:140

References submap::get_items(), get_submap_at(), inbounds(), and nulitems.

Referenced by computer_session::action_blood_anal(), computer_session::action_conveyor(), computer_session::action_data_anal(), computer_session::action_irradiator(), computer_session::action_list_bionics(), computer_session::action_sample(), Character::activate_bionic(), activity_on_turn_move_loot(), add_item_or_charges(), advanced_inventory_pane::add_items_from_area(), iexamine::aggie_plant(), apply_camp_ownership(), apply_faction_ownership(), iexamine::arcfurnace_empty(), iexamine::arcfurnace_full(), are_requirements_nearby(), iexamine::autoclave_full(), Character::base_comfort_value(), bash_furn_success(), bash_items(), board_up(), MapExtras::burned_ground_parser(), game::butcher(), butcher_corpse_activity(), can_butcher_at(), can_do_activity_there(), iexamine::can_fertilize(), advanced_inventory::change_square(), construct::check_empty(), chop_plank_activity(), doors::close_door(), complete_construction(), iuse::directional_antenna(), iexamine::dirtmound(), displace_items_except_one_liquid(), basecamp::distribute_food(), construct::done_grave(), drop_furniture(), drop_items(), editmap::edit_itm(), iexamine::elevator(), explosion_handler::emp_blast(), game::examine(), computer_session::failure_destroy_blood(), computer_session::failure_destroy_data(), farm_action(), iexamine::fertilize_plant(), fetch_activity(), talk_function::field_harvest(), fill_funnels(), activity_handlers::fill_liquid_do_turn(), find_auto_consume(), npc::find_corpse_to_pulp(), npc::find_item(), game::find_nearby_items(), flammable_items_at(), Character::floor_item_warmth(), game::forced_door_closing(), basecamp::form_crafting_inventory(), inventory::form_from_map(), free_volume(), fromPumpFuel(), furnname(), iexamine::fvat_empty(), iexamine::fvat_full(), iexamine::gaspump(), generate_lightmap(), generic_multi_activity_locations(), advanced_inv_area::get_container(), player::get_eligible_containers_for_crafting(), advanced_inv_area::get_item_count(), iexamine::getNearFilledGasTank(), game::grabbed_furn_move(), grow_plant(), liquid_handler::handle_liquid_from_ground(), iexamine::harvest_plant(), i_at(), i_rem(), Character::is_snuggling(), activity_handlers::jackhammer_finish(), iexamine::keg(), iexamine::kiln_empty(), iexamine::kiln_full(), advanced_inventory_pane::load_settings(), activity_handlers::longsalvage_finish(), talk_function::loot_building(), max_volume(), mill_activate(), iexamine::mill_finalize(), mop_spills(), advanced_inventory::move_all_items(), MapExtras::mx_supplydrop(), iuse::note_bionics(), om_harvest_itm(), iexamine::pedestal_temple(), iexamine::pedestal_wyrm(), tutorial_game::per_turn(), npc::pick_up_item_map(), activity_handlers::pickaxe_finish(), game::place_player(), iexamine::pour_into_keg(), firestarter_actor::prep_firestarter_use(), game::print_items_info(), process_fields_in_submap(), process_items_in_submap(), produce_sap(), activity_handlers::pulp_do_turn(), iexamine::quern_examine(), plot_options::query_seed(), iexamine::recycle_compactor(), iexamine::reload_furniture(), requirements_map(), rod_fish(), npc::see_item_say_smth(), serialize_liquid_source(), iexamine::shrub_wildveggies(), smash(), smash_items(), smoker_activate(), smoker_finalize(), iexamine::smoker_options(), spell_move(), fungal_effects::spread_fungus_one_tile(), game::start_hauling(), basecamp::start_relay_hide_site(), stored_volume(), tidy_activity(), tinder_at(), iexamine::toilet(), iexamine::toPumpFuel(), iexamine::tree_maple_tapped(), try_fuel_fire(), editmap::update_view_with_help(), enzlave_actor::use(), use_amount_square(), use_charges(), use_charges_from_furn(), iexamine::use_furn_fake_item(), and iexamine::vending().

◆ i_clear() [1/2]

void map::i_clear ( const point p)
inline

Definition at line 1245 of file map.h.

1245 {
1246 i_clear( tripoint( p, abs_sub.z ) );
1247 }

References abs_sub, i_clear(), and tripoint::z.

◆ i_clear() [2/2]

void map::i_clear ( const tripoint p)

Definition at line 4128 of file map.cpp.

4129{
4130 point l;
4131 submap *const current_submap = get_submap_at( p, l );
4132
4133 for( item &it : current_submap->get_items( l ) ) {
4134 // remove from the active items cache (if it isn't there does nothing)
4135 current_submap->active_items.remove( &it );
4136 }
4137 if( current_submap->active_items.empty() ) {
4138 submaps_with_active_items.erase( tripoint( abs_sub.x + p.x / SEEX, abs_sub.y + p.y / SEEY, p.z ) );
4139 }
4140
4141 current_submap->set_lum( l, 0 );
4142 current_submap->get_items( l ).clear();
4143}
void remove(const item *it)
Removes the item if it is in the cache.
void set_lum(const point &p, uint8_t luminance)
Definition: submap.h:125

References abs_sub, submap::active_items, active_item_cache::empty(), submap::get_items(), get_submap_at(), active_item_cache::remove(), SEEX, SEEY, submap::set_lum(), submaps_with_active_items, tripoint::x, tripoint::y, and tripoint::z.

Referenced by computer_session::action_conveyor(), iexamine::aggie_plant(), jmapgen_terrain::apply(), iexamine::arcfurnace_empty(), board_up(), doors::close_door(), MapExtras::dead_vegetation_parser(), basecamp::distribute_food(), draw_lab(), drop_furniture(), drop_items(), computer_session::failure_destroy_blood(), computer_session::failure_destroy_data(), farm_action(), iexamine::fertilize_plant(), talk_function::field_harvest(), iexamine::fvat_empty(), iexamine::fvat_full(), game::grabbed_furn_move(), grow_plant(), iexamine::harvest_plant(), i_clear(), iexamine::keg(), iexamine::kiln_empty(), mapgen_lake_shore(), om_harvest_itm(), iexamine::pedestal_temple(), iexamine::pedestal_wyrm(), rad_scorch(), and iexamine::tree_maple_tapped().

◆ i_rem() [1/4]

map_stack::iterator map::i_rem ( const point location,
map_stack::const_iterator  it 
)
inline

Definition at line 1251 of file map.h.

1251 {
1252 return i_rem( tripoint( location, abs_sub.z ), it );
1253 }
map_stack::iterator i_rem(const tripoint &p, map_stack::const_iterator it)
Definition: map.cpp:4103

References abs_sub, i_rem(), and tripoint::z.

◆ i_rem() [2/4]

void map::i_rem ( const point p,
item it 
)
inline

Definition at line 1255 of file map.h.

1255 {
1256 i_rem( tripoint( p, abs_sub.z ), it );
1257 }

References abs_sub, i_rem(), and tripoint::z.

◆ i_rem() [3/4]

void map::i_rem ( const tripoint p,
item it 
)

Definition at line 4119 of file map.cpp.

4120{
4121 map_stack map_items = i_at( p );
4123 if( iter != map_items.end() ) {
4124 i_rem( p, iter );
4125 }
4126}
iterator get_iterator_from_pointer(item *it)
Definition: item_stack.cpp:68

References item_stack::end(), item_stack::get_iterator_from_pointer(), i_at(), and i_rem().

◆ i_rem() [4/4]

map_stack::iterator map::i_rem ( const tripoint p,
map_stack::const_iterator  it 
)

Definition at line 4103 of file map.cpp.

4104{
4105 point l;
4106 submap *const current_submap = get_submap_at( p, l );
4107
4108 // remove from the active items cache (if it isn't there does nothing)
4109 current_submap->active_items.remove( &*it );
4110 if( current_submap->active_items.empty() ) {
4111 submaps_with_active_items.erase( tripoint( abs_sub.x + p.x / SEEX, abs_sub.y + p.y / SEEY, p.z ) );
4112 }
4113
4114 current_submap->update_lum_rem( l, *it );
4115
4116 return current_submap->get_items( l ).erase( it );
4117}
void update_lum_rem(const point &p, const item &i)
Definition: submap.h:137

References abs_sub, submap::active_items, active_item_cache::empty(), submap::get_items(), get_submap_at(), active_item_cache::remove(), SEEX, SEEY, submaps_with_active_items, submap::update_lum_rem(), tripoint::x, tripoint::y, and tripoint::z.

Referenced by computer_session::action_irradiator(), chop_plank_activity(), delete_cyborg_item(), iexamine::elevator(), map_stack::erase(), iexamine::fvat_full(), i_rem(), mill_activate(), move_item(), om_set_hide_site(), rcdrive(), remove_rotten_items(), smash_items(), and smoker_activate().

◆ impassable() [1/2]

bool map::impassable ( const point p) const
inline

Definition at line 627 of file map.h.

627 {
628 return !passable( p );
629 }

References passable().

◆ impassable() [2/2]

◆ impassable_ter_furn()

bool map::impassable_ter_furn ( const tripoint p) const

Definition at line 1828 of file map.cpp.

1829{
1830 return !passable_ter_furn( p );
1831}
bool passable_ter_furn(const tripoint &p) const
Definition: map.cpp:1833

References passable_ter_furn().

Referenced by vehicle::check_heli_ascend(), vehicle::check_heli_descend(), climb_difficulty(), displace_water(), and vehicle::part_collision().

◆ inbounds() [1/2]

bool map::inbounds ( const point p) const
inline

Definition at line 1668 of file map.h.

1668 {
1669 return inbounds( tripoint( p, 0 ) );
1670 }

References inbounds().

◆ inbounds() [2/2]

bool map::inbounds ( const tripoint p) const
virtual

Reimplemented in tinymap.

Definition at line 7769 of file map.cpp.

7770{
7771 static constexpr tripoint map_boundary_min( 0, 0, -OVERMAP_DEPTH );
7772 static constexpr tripoint map_boundary_max( MAPSIZE_Y, MAPSIZE_X, OVERMAP_HEIGHT + 1 );
7773
7774 static constexpr half_open_cuboid<tripoint> map_boundaries(
7775 map_boundary_min, map_boundary_max );
7776
7777 return map_boundaries.contains( p );
7778}

References half_open_cuboid< Tripoint, >::contains(), MAPSIZE_X, MAPSIZE_Y, OVERMAP_DEPTH, and OVERMAP_HEIGHT.

Referenced by vehicle::act_on_map(), activity_on_turn_move_loot(), add_field(), add_item(), MapgenRemovePartHandler::add_item_or_charges(), add_item_or_charges(), add_vehicle(), add_vehicle_to_cache(), adjust_radiation(), ambient_light_at(), grid_furn_transform_queue::apply(), apply_light_source(), apply_vision_transparency_cache(), bash(), bash_rating(), build_sunlight_cache(), Character::check_outbounds_activity(), clear_path(), clear_vehicle_cache(), clear_vehicle_point_from_cache(), computer_at(), delete_graffiti(), delete_signage(), displace_vehicle(), explosion_handler::do_blast(), do_vehicle_caching(), draw(), game::draw_look_around_cursor(), drawsq(), ranged::execute_shaped_attack(), field_at(), furn(), furn_set(), generate_lightmap(), generic_multi_activity_handler(), get_field(), get_known_connections(), get_radiation(), get_signage(), get_submap_at(), get_temperature(), graffiti_at(), has_flag_ter_or_furn(), has_floor(), has_graffiti_at(), has_items(), i_at(), inbounds(), is_bashable(), is_outside(), light_at(), game::load_npcs(), maptile_at(), map_stack::max_volume(), move_cost(), move_cost_ter_furn(), obscured_by_vehicle_rotation(), obstructed_by_vehicle_rotation(), activity_handlers::operation_do_turn(), partial_con_at(), partial_con_remove(), partial_con_set(), pl_line_of_sight(), pl_sees(), game::print_all_tile_info(), remove_field(), remove_trap(), restore_vision_transparency_cache(), route(), npc::saw_player_recently(), sees(), set_graffiti(), set_radiation(), set_seen_cache_dirty(), set_signage(), set_temperature(), set_transparency_cache_dirty(), game::shift_monsters(), shift_traps(), shoot(), spawn_items(), ter(), ter_set(), tr_at(), trap_set(), update_suspension_cache(), valid_move(), and veh_at().

◆ inbounds_z()

◆ invalidate_map_cache()

◆ invalidate_max_populated_zlev()

void map::invalidate_max_populated_zlev ( int  zlev)
private

Conditionally invalidates max_pupulated_zlev cache if the submap uniformity change occurs above current max_pupulated_zlev value.

Parameters
zlevzlevel where uniformity change occured

Definition at line 8993 of file map.cpp.

8994{
8995 if( max_populated_zlev && max_populated_zlev->second < zlev ) {
8996 max_populated_zlev->second = zlev;
8997 }
8998}

References max_populated_zlev.

Referenced by add_field(), add_item(), add_vehicle(), displace_vehicle(), furn_set(), shift_vehicle_z(), and ter_set().

◆ is_bashable() [1/2]

bool map::is_bashable ( const point p) const
inline

Definition at line 1021 of file map.h.

1021 {
1022 return is_bashable( tripoint( p, abs_sub.z ) );
1023 }

References abs_sub, is_bashable(), and tripoint::z.

◆ is_bashable() [2/2]

bool map::is_bashable ( const tripoint p,
bool  allow_floor = false 
) const

Returns true if there is a bashable vehicle part or the furn/terrain is bashable at p.

Definition at line 2425 of file map.cpp.

2426{
2427 if( !inbounds( p ) ) {
2428 dbg( DL::Warn ) << "Looking for out-of-bounds is_bashable at " << p;
2429 return false;
2430 }
2431
2432 if( veh_at( p ).obstacle_at_part() ) {
2433 return true;
2434 }
2435
2436 if( has_furn( p ) && furn( p ).obj().bash.str_max != -1 ) {
2437 return true;
2438 }
2439
2440 const auto &ter_bash = ter( p ).obj().bash;
2441 return ter_bash.str_max != -1 && ( !ter_bash.bash_below || allow_floor );
2442}

References bash(), map_data_common_t::bash, dbg, furn(), has_furn(), inbounds(), int_id< T >::obj(), map_bash_info::str_max, ter(), veh_at(), and Warn.

Referenced by MapExtras::burned_ground_parser(), activity_handlers::burrow_finish(), features(), game::fling_creature(), is_bashable(), npc::move_to(), MapExtras::mx_helicopter(), and activity_handlers::pickaxe_finish().

◆ is_bashable_furn() [1/2]

bool map::is_bashable_furn ( const point p) const
inline

Definition at line 1031 of file map.h.

1031 {
1032 return is_bashable_furn( tripoint( p, abs_sub.z ) );
1033 }
bool is_bashable_furn(const tripoint &p) const
Returns true if the furniture at p is bashable.
Definition: map.cpp:2450

References abs_sub, is_bashable_furn(), and tripoint::z.

◆ is_bashable_furn() [2/2]

bool map::is_bashable_furn ( const tripoint p) const

Returns true if the furniture at p is bashable.

Definition at line 2450 of file map.cpp.

2451{
2452 return has_furn( p ) && furn( p ).obj().bash.str_max != -1;
2453}

References map_data_common_t::bash, furn(), has_furn(), int_id< T >::obj(), and map_bash_info::str_max.

Referenced by is_bashable_furn(), is_bashable_ter_furn(), and make_rubble().

◆ is_bashable_ter() [1/2]

bool map::is_bashable_ter ( const point p) const
inline

Definition at line 1026 of file map.h.

1026 {
1027 return is_bashable_ter( tripoint( p, abs_sub.z ) );
1028 }
bool is_bashable_ter(const tripoint &p, bool allow_floor=false) const
Returns true if the terrain at p is bashable.
Definition: map.cpp:2444

References abs_sub, is_bashable_ter(), and tripoint::z.

◆ is_bashable_ter() [2/2]

bool map::is_bashable_ter ( const tripoint p,
bool  allow_floor = false 
) const

Returns true if the terrain at p is bashable.

Definition at line 2444 of file map.cpp.

2445{
2446 const auto &ter_bash = ter( p ).obj().bash;
2447 return ter_bash.str_max != -1 && ( !ter_bash.bash_below || allow_floor );
2448}

References map_data_common_t::bash, int_id< T >::obj(), map_bash_info::str_max, and ter().

Referenced by is_bashable_ter(), is_bashable_ter_furn(), and make_rubble().

◆ is_bashable_ter_furn() [1/2]

bool map::is_bashable_ter_furn ( const point p) const
inline

Definition at line 1036 of file map.h.

1036 {
1037 return is_bashable_ter_furn( tripoint( p, abs_sub.z ) );
1038 }
bool is_bashable_ter_furn(const tripoint &p, bool allow_floor=false) const
Returns true if the furniture or terrain at p is bashable.
Definition: map.cpp:2455

References abs_sub, is_bashable_ter_furn(), and tripoint::z.

◆ is_bashable_ter_furn() [2/2]

bool map::is_bashable_ter_furn ( const tripoint p,
bool  allow_floor = false 
) const

Returns true if the furniture or terrain at p is bashable.

Definition at line 2455 of file map.cpp.

2456{
2457 return is_bashable_furn( p ) || is_bashable_ter( p, allow_floor );
2458}

References is_bashable_furn(), and is_bashable_ter().

Referenced by is_bashable_ter_furn(), and vehicle::part_collision().

◆ is_cornerfloor()

bool map::is_cornerfloor ( const tripoint p) const

Definition at line 8930 of file map.cpp.

8931{
8932 if( impassable( p ) ) {
8933 return false;
8934 }
8935 std::set<tripoint> impassable_adjacent;
8936 for( const tripoint &pt : points_in_radius( p, 1 ) ) {
8937 if( impassable( pt ) ) {
8938 impassable_adjacent.insert( pt );
8939 }
8940 }
8941 if( !impassable_adjacent.empty() ) {
8942 //to check if a floor is a corner we first search if any of its diagonal adjacent points is impassable
8943 std::set< tripoint> diagonals = { p + tripoint_north_east, p + tripoint_north_west, p + tripoint_south_east, p + tripoint_south_west };
8944 for( const tripoint &impassable_diagonal : diagonals ) {
8945 if( impassable_adjacent.count( impassable_diagonal ) != 0 ) {
8946 //for every impassable diagonal found, we check if that diagonal terrain has at least two impassable neighbors that also neighbor point p
8947 int f = 0;
8948 for( const tripoint &l : points_in_radius( impassable_diagonal, 1 ) ) {
8949 if( impassable_adjacent.count( l ) != 0 ) {
8950 f++;
8951 }
8952 if( f > 2 ) {
8953 return true;
8954 }
8955 }
8956 }
8957 }
8958 }
8959 return false;
8960}
static constexpr tripoint tripoint_north_east
Definition: point.h:286
static constexpr tripoint tripoint_north_west
Definition: point.h:292
static constexpr tripoint tripoint_south_east
Definition: point.h:288
static constexpr tripoint tripoint_south_west
Definition: point.h:290

References impassable(), points_in_radius(), tripoint_north_east, tripoint_north_west, tripoint_south_east, and tripoint_south_west.

◆ is_divable() [1/2]

bool map::is_divable ( const point p) const
inline

Definition at line 1079 of file map.h.

1079 {
1080 return is_divable( tripoint( p, abs_sub.z ) );
1081 }
bool is_divable(const tripoint &p) const
Returns whether or not the terrain at the given location can be dived into (by monsters that can swim...
Definition: map.cpp:2569

References abs_sub, is_divable(), and tripoint::z.

◆ is_divable() [2/2]

bool map::is_divable ( const tripoint p) const

Returns whether or not the terrain at the given location can be dived into (by monsters that can swim or are aquatic or non-breathing).

Parameters
pThe coordinate to look at.
Returns
true if the terrain can be dived into; false if not.

Definition at line 2569 of file map.cpp.

2570{
2571 return has_flag( "SWIMMABLE", p ) && has_flag( TFLAG_DEEP_WATER, p );
2572}

References has_flag(), and TFLAG_DEEP_WATER.

Referenced by enchantment::is_active(), is_divable(), and Creature::sees().

◆ is_flammable()

bool map::is_flammable ( const tripoint p)

Returns true if there is a flammable item or field or the furn/terrain is flammable at p.

Definition at line 2653 of file map.cpp.

2654{
2655 if( flammable_items_at( p ) ) {
2656 return true;
2657 }
2658
2659 if( has_flag( "FLAMMABLE", p ) ) {
2660 return true;
2661 }
2662
2663 if( has_flag( "FLAMMABLE_ASH", p ) ) {
2664 return true;
2665 }
2666
2667 if( get_field_intensity( p, fd_web ) > 0 ) {
2668 return true;
2669 }
2670
2671 return false;
2672}
int get_field_intensity(const tripoint &p, const field_type_id &type) const
Get the intensity of a field entry (field_entry::intensity), if there is no field of that type,...
Definition: map.cpp:5379
bool flammable_items_at(const tripoint &p, int threshold=0)
Checks if there are any flammable items on the tile.
Definition: map.cpp:2636

References fd_web, flammable_items_at(), get_field_intensity(), and has_flag().

Referenced by Character::activate_bionic(), and activity_handlers::start_fire_do_turn().

◆ is_harvestable()

bool map::is_harvestable ( const tripoint pos) const

Returns true if point at pos is harvestable right now, with no extra tools.

Definition at line 1630 of file map.cpp.

1631{
1632 const auto &harvest_here = get_harvest( pos );
1633 return !harvest_here.is_null() && !harvest_here->empty();
1634}
const harvest_id & get_harvest(const tripoint &p) const
Returns the full harvest list, for spawning.
Definition: map.cpp:1564

References get_harvest(), and wrapped_vehicle::pos.

Referenced by npc::pick_up_item().

◆ is_last_ter_wall()

bool map::is_last_ter_wall ( bool  no_furn,
const point p,
const point max,
direction  dir 
) const

Check if the last terrain is wall in direction NORTH, SOUTH, WEST or EAST.

Parameters
no_furnif true, the function will stop and return false if it encounters a furniture
pstarting coordinates of check
maxending coordinates of check
dirDirection of check
Returns
true if from x to xmax or y to ymax depending on direction all terrain is floor and the last terrain is a wall

Definition at line 2584 of file map.cpp.

2586{
2587 point mov;
2588 switch( dir ) {
2589 case direction::NORTH:
2590 mov.y = -1;
2591 break;
2592 case direction::SOUTH:
2593 mov.y = 1;
2594 break;
2595 case direction::WEST:
2596 mov.x = -1;
2597 break;
2598 case direction::EAST:
2599 mov.x = 1;
2600 break;
2601 default:
2602 break;
2603 }
2604 point p2( p );
2605 bool result = true;
2606 bool loop = true;
2607 while( ( loop ) && ( ( dir == direction::NORTH && p2.y >= 0 ) ||
2608 ( dir == direction::SOUTH && p2.y < max.y ) ||
2609 ( dir == direction::WEST && p2.x >= 0 ) ||
2610 ( dir == direction::EAST && p2.x < max.x ) ) ) {
2611 if( no_furn && has_furn( p2 ) ) {
2612 loop = false;
2613 result = false;
2614 } else if( !has_flag_ter( "FLAT", p2 ) ) {
2615 loop = false;
2616 if( !has_flag_ter( "WALL", p2 ) ) {
2617 result = false;
2618 }
2619 }
2620 p2.x += mov.x;
2621 p2.y += mov.y;
2622 }
2623 return result;
2624}

References EAST, has_flag_ter(), has_furn(), NORTH, SOUTH, WEST, point::x, and point::y.

Referenced by find_potential_computer_point().

◆ is_outside() [1/2]

bool map::is_outside ( const point p) const
inline

Definition at line 1069 of file map.h.

1069 {
1070 return is_outside( tripoint( p, abs_sub.z ) );
1071 }
bool is_outside(const tripoint &p) const
Definition: map.cpp:2574

References abs_sub, is_outside(), and tripoint::z.

◆ is_outside() [2/2]

◆ is_suspension_valid()

bool map::is_suspension_valid ( const tripoint point)

Checks the four orientations in which a suspended tile could be valid, and returns if the tile is valid.

Definition at line 2973 of file map.cpp.

2974{
2975 if( ter( point + tripoint_east ) != t_open_air
2976 && ter( point + tripoint_west ) != t_open_air ) {
2977 return true;
2978 }
2981 return true;
2982 }
2984 && ter( point + tripoint_north ) != t_open_air ) {
2985 return true;
2986 }
2989 return true;
2990 }
2991 return false;
2992}
static constexpr tripoint tripoint_north
Definition: point.h:285
static constexpr tripoint tripoint_west
Definition: point.h:291
static constexpr tripoint tripoint_east
Definition: point.h:287
static constexpr tripoint tripoint_south
Definition: point.h:289

References t_open_air, ter(), tripoint_east, tripoint_north, tripoint_north_east, tripoint_north_west, tripoint_south, tripoint_south_east, tripoint_south_west, and tripoint_west.

Referenced by collapse_invalid_suspension(), and update_suspension_cache().

◆ is_transparent()

bool map::is_transparent ( const tripoint p) const

Returns whether the tile at p is transparent(you can look past it).

Definition at line 655 of file lightmap.cpp.

656{
658}

References light_transparency(), and LIGHT_TRANSPARENCY_SOLID.

Referenced by ranged::execute_shaped_attack(), ranged::expected_coverage(), get_known_connections(), mattack::riotbot(), and shoot().

◆ is_wall_adjacent()

bool map::is_wall_adjacent ( const tripoint center) const

Definition at line 1768 of file map.cpp.

1769{
1770 for( const tripoint &p : points_in_radius( center, 1 ) ) {
1771 if( p != center && impassable( p ) ) {
1772 return true;
1773 }
1774 }
1775 return false;
1776}

References center, impassable(), and points_in_radius().

Referenced by ma_requirements::is_valid_character().

◆ is_water_shallow_current() [1/2]

bool map::is_water_shallow_current ( const point p) const
inline

Definition at line 1083 of file map.h.

1083 {
1085 }
bool is_water_shallow_current(const tripoint &p) const
Definition: map.cpp:2564

References abs_sub, is_water_shallow_current(), and tripoint::z.

◆ is_water_shallow_current() [2/2]

bool map::is_water_shallow_current ( const tripoint p) const

Definition at line 2564 of file map.cpp.

2565{
2566 return has_flag( "CURRENT", p ) && !has_flag( TFLAG_DEEP_WATER, p );
2567}

References has_flag(), and TFLAG_DEEP_WATER.

Referenced by is_water_shallow_current(), and iexamine::quern_examine().

◆ light_at()

lit_level map::light_at ( const tripoint p) const

Definition at line 621 of file lightmap.cpp.

622{
623 if( !inbounds( p ) ) {
624 return lit_level::DARK; // Out of bounds
625 }
626
627 const auto &map_cache = get_cache_ref( p.z );
628 const auto &lm = map_cache.lm;
629 const auto &sm = map_cache.sm;
630 if( sm[p.x][p.y] >= LIGHT_SOURCE_BRIGHT ) {
631 return lit_level::BRIGHT;
632 }
633
634 const float max_light = lm[p.x][p.y].max();
635 if( max_light >= LIGHT_AMBIENT_LIT ) {
636 return lit_level::LIT;
637 }
638
639 if( max_light >= LIGHT_AMBIENT_LOW ) {
640 return lit_level::LOW;
641 }
642
643 return lit_level::DARK;
644}

References BRIGHT, DARK, get_cache_ref(), inbounds(), LIGHT_AMBIENT_LIT, LIGHT_AMBIENT_LOW, LIGHT_SOURCE_BRIGHT, LIT, LOW, coords::sm, tripoint::x, tripoint::y, and tripoint::z.

Referenced by Creature::sees().

◆ light_transparency()

float map::light_transparency ( const tripoint p) const

Definition at line 660 of file lightmap.cpp.

661{
662 return get_cache_ref( p.z ).transparency_cache[p.x][p.y];
663}

References get_cache_ref(), level_cache::transparency_cache, tripoint::x, tripoint::y, and tripoint::z.

Referenced by generate_lightmap(), and is_transparent().

◆ load() [1/2]

void map::load ( const tripoint w,
bool  update_vehicles,
bool  pump_events = false 
)

Load submaps into grid.

This might create new submaps if the mapbuffer can not deliver the requested submap (as it does not exist on disc). This must be called before the map can be used at all!

Parameters
wglobal coordinates of the submap at grid[0]. This is in submap coordinates.
update_vehiclesIf true, add vehicles to the vehicle cache.
pump_eventsIf true, handle window events during loading. If you set this to true, do ensure that the map is not accessed before this function returns (for example, UIs that draw the map should be disabled).

Definition at line 6622 of file map.cpp.

6623{
6624 for( auto &traps : traplocs ) {
6625 traps.clear();
6626 }
6627 field_furn_locs.clear();
6629 set_abs_sub( w );
6630 for( int gridx = 0; gridx < my_MAPSIZE; gridx++ ) {
6631 for( int gridy = 0; gridy < my_MAPSIZE; gridy++ ) {
6632 loadn( point( gridx, gridy ), update_vehicle );
6633 if( pump_events ) {
6635 }
6636 }
6637 }
6639}
void pump_events()
Resize & refresh if necessary, process all pending window events, and ignore keypresses.
void loadn(const tripoint &grid, bool update_vehicles)
Definition: map.cpp:7004
input_manager inp_mngr
Definition: input.cpp:109

References field_furn_locs, inp_mngr, loadn(), my_MAPSIZE, input_manager::pump_events(), reset_vehicle_cache(), set_abs_sub(), submaps_with_active_items, and traplocs.

Referenced by start_location::add_map_extra(), add_monsters(), start_location::burn(), talk_function::buy_100_logs(), talk_function::buy_10_logs(), create_lab_consoles(), debug_menu::debug(), construct::done_digormine_stair(), construct::done_mine_upstair(), farm_action(), talk_function::field_build_1(), talk_function::field_build_2(), talk_function::field_harvest(), talk_function::field_plant(), find_valid_teleporters_omt(), basecamp::form_crafting_inventory(), mission_start::kill_horde_master(), load(), game::load_map(), talk_function::loot_building(), editmap::mapgen_veh_destroy(), editmap::mapgen_veh_query(), MapExtras::mx_minefield(), om_cutdown_trees(), om_harvest_furn(), om_harvest_itm(), om_harvest_ter(), om_set_hide_site(), teleporter_list::place_avatar_overmap(), Character::place_corpse(), mission_start::place_deposit_box(), mission_start::place_dog(), mission_start::place_npc_software(), mission_start::place_priest_diary(), basecamp::place_results(), game::place_vehicle_nearby(), mission_start::place_zombie_mom(), start_location::prepare_map(), mission_start::ranch_nurse_1(), mission_start::ranch_nurse_2(), mission_start::ranch_nurse_3(), mission_start::ranch_nurse_4(), mission_start::ranch_nurse_5(), mission_start::ranch_nurse_6(), mission_start::ranch_nurse_7(), mission_start::ranch_nurse_8(), mission_start::ranch_nurse_9(), mission_start::ranch_scavenger_1(), mission_start::ranch_scavenger_2(), mission_start::ranch_scavenger_3(), mission_start::reveal_lab_train_depot(), debug_menu::spawn_nested_mapgen(), basecamp::start_relay_hide_site(), update_mapgen_function_json::update_map(), game::vertical_move(), and game::vertical_shift().

◆ load() [2/2]

void map::load ( const tripoint_abs_sm w,
bool  update_vehicles,
bool  pump_events = false 
)

Definition at line 6641 of file map.cpp.

6642{
6643 // TODO: fix point types
6644 load( w.raw(), update_vehicle, pump_events );
6645}
constexpr Point & raw()
Definition: coordinates.h:111
void load(const tripoint &w, bool update_vehicles, bool pump_events=false)
Load submaps into grid.
Definition: map.cpp:6622

References load(), and coords::coord_point< Point, Origin, Scale >::raw().

◆ loadn() [1/2]

void map::loadn ( const point grid,
bool  update_vehicles 
)
inlineprotected

Definition at line 1722 of file map.h.

1722 {
1723 if( zlevels ) {
1724 for( int gridz = -OVERMAP_DEPTH; gridz <= OVERMAP_HEIGHT; gridz++ ) {
1725 loadn( tripoint( grid, gridz ), update_vehicles );
1726 }
1727
1728 // Note: we want it in a separate loop! It is a post-load cleanup
1729 // Since we're adding roofs, we want it to go up (from lowest to highest)
1730 for( int gridz = -OVERMAP_DEPTH; gridz <= OVERMAP_HEIGHT; gridz++ ) {
1731 add_roofs( tripoint( grid, gridz ) );
1732 }
1733 } else {
1734 loadn( tripoint( grid, abs_sub.z ), update_vehicles );
1735 }
1736 }
void add_roofs(const tripoint &grid)
Hacks in missing roofs.
Definition: map.cpp:7473

References abs_sub, add_roofs(), grid, loadn(), OVERMAP_DEPTH, OVERMAP_HEIGHT, tripoint::z, and zlevels.

◆ loadn() [2/2]

void map::loadn ( const tripoint grid,
bool  update_vehicles 
)
protected

Definition at line 7004 of file map.cpp.

7005{
7006 // Cache empty overmap types
7007 static const oter_id rock( "empty_rock" );
7008 static const oter_id air( "open_air" );
7009
7010 const tripoint grid_abs_sub = abs_sub.xy() + grid;
7011 const size_t gridn = get_nonant( grid );
7012
7013 const int old_abs_z = abs_sub.z; // Ugly, but necessary at the moment
7014 abs_sub.z = grid.z;
7015
7016 submap *tmpsub = MAPBUFFER.lookup_submap( grid_abs_sub );
7017 if( tmpsub == nullptr ) {
7018 // It doesn't exist; we must generate it!
7019 dbg( DL::Info ) << "map::loadn: Missing mapbuffer data. Regenerating.";
7020
7021 // Each overmap square is two nonants; to prevent overlap, generate only at
7022 // squares divisible by 2.
7023 // TODO: fix point types
7024 const tripoint_abs_omt grid_abs_omt( sm_to_omt_copy( grid_abs_sub ) );
7025 const tripoint grid_abs_sub_rounded = omt_to_sm_copy( grid_abs_omt.raw() );
7026
7027 const oter_id terrain_type = overmap_buffer.ter( grid_abs_omt );
7028
7029 // Short-circuit if the map tile is uniform
7030 // TODO: Replace with json mapgen functions.
7031 if( terrain_type == air ) {
7032 generate_uniform( grid_abs_sub_rounded, t_open_air );
7033 } else if( terrain_type == rock ) {
7034 generate_uniform( grid_abs_sub_rounded, t_rock );
7035 } else {
7036 tinymap tmp_map;
7037 tmp_map.generate( grid_abs_sub_rounded, calendar::turn );
7038 }
7039
7040 // This is the same call to MAPBUFFER as above!
7041 tmpsub = MAPBUFFER.lookup_submap( grid_abs_sub );
7042 if( tmpsub == nullptr ) {
7043 debugmsg( "failed to generate a submap at %s", grid_abs_sub.to_string() );
7044 return;
7045 }
7046 }
7047
7048 // New submap changes the content of the map and all caches must be recalculated
7055 setsubmap( gridn, tmpsub );
7056 if( !tmpsub->active_items.empty() ) {
7057 submaps_with_active_items.emplace( grid_abs_sub );
7058 }
7059 if( tmpsub->field_count > 0 ) {
7060 get_cache( grid.z ).field_cache.set( grid.x + grid.y * MAPSIZE );
7061 }
7062 // Destroy bugged no-part vehicles
7063 auto &veh_vec = tmpsub->vehicles;
7064 for( auto iter = veh_vec.begin(); iter != veh_vec.end(); ) {
7065 vehicle *veh = iter->get();
7066 if( veh->part_count() > 0 ) {
7067 // Always fix submap coordinates for easier Z-level-related operations
7068 veh->sm_pos = grid;
7069 veh->attach();
7070 iter++;
7071 } else {
7073 if( veh->tracking_on ) {
7075 }
7076 dirty_vehicle_list.erase( veh );
7077 iter = veh_vec.erase( iter );
7078 }
7079 }
7080
7081 // Update vehicle data
7082 if( update_vehicles ) {
7083 auto &map_cache = get_cache( grid.z );
7084 for( const auto &veh : tmpsub->vehicles ) {
7085 // Only add if not tracking already.
7086 if( map_cache.vehicle_list.find( veh.get() ) == map_cache.vehicle_list.end() ) {
7087 map_cache.vehicle_list.insert( veh.get() );
7088 if( !veh->loot_zones.empty() ) {
7089 map_cache.zone_vehicles.insert( veh.get() );
7090 }
7091 add_vehicle_to_cache( veh.get() );
7092 }
7093 }
7094 }
7095
7096 actualize( grid );
7097
7098 abs_sub.z = old_abs_z;
7099}
void set_suspension_cache_dirty(const int zlev)
Definition: map.h:454
void generate(const tripoint &p, const time_point &when)
Definition: mapgen.cpp:107
void actualize(const tripoint &grid)
Fast forward a submap that has just been loading into this map.
Definition: map.cpp:7419
submap * lookup_submap(const tripoint &p)
Get a submap stored in this buffer.
Definition: mapbuffer.cpp:88
Definition: map.h:2108
std::unordered_multimap< point, zone_data > loot_zones
Definition: vehicle.h:1863
int part_count() const
Definition: vehicle.cpp:7075
void attach()
Definition: vehicle.h:764
point omt_to_sm_copy(const point &p)
static void generate_uniform(const tripoint &p, const ter_id &terrain_type)
Definition: map.cpp:6988
mapbuffer MAPBUFFER
Definition: mapbuffer.cpp:40

References abs_sub, submap::active_items, actualize(), add_vehicle_to_cache(), vehicle::attach(), dbg, debugmsg, dirty_vehicle_list, active_item_cache::empty(), level_cache::field_cache, submap::field_count, generate(), generate_uniform(), get_cache(), get_nonant(), grid, Info, mapbuffer::lookup_submap(), MAPBUFFER, MAPSIZE, omt_to_sm_copy(), overmap_buffer, vehicle::part_count(), coords::coord_point< Point, Origin, Scale >::raw(), overmapbuffer::remove_vehicle(), reset_vehicle_cache(), set_floor_cache_dirty(), set_outside_cache_dirty(), set_pathfinding_cache_dirty(), set_seen_cache_dirty(), set_suspension_cache_dirty(), set_transparency_cache_dirty(), setsubmap(), vehicle::sm_pos, sm_to_omt_copy(), submaps_with_active_items, t_open_air, t_rock, overmapbuffer::ter(), tripoint::to_string(), vehicle::tracking_on, calendar::turn, submap::vehicles, tripoint::xy(), and tripoint::z.

Referenced by load(), loadn(), and shift().

◆ make_active()

void map::make_active ( item_location loc)

Update an item's active status, for example when adding hot or perishable liquid to a container.

Definition at line 4427 of file map.cpp.

4428{
4429 item *target = loc.get_item();
4430
4431 // Trust but verify, don't let stinking callers set items active when they shouldn't be.
4432 if( !target->needs_processing() ) {
4433 return;
4434 }
4435 point l;
4436 submap *const current_submap = get_submap_at( loc.position(), l );
4437 cata::colony<item> &item_stack = current_submap->get_items( l );
4439
4440 if( current_submap->active_items.empty() ) {
4442 abs_sub.y + loc.position().y / SEEY, loc.position().z ) );
4443 }
4444 current_submap->active_items.add( *iter, l );
4445}
item * get_item()
Gets the selected item or nullptr.
tripoint position() const
Returns the position where the item is found.

References abs_sub, submap::active_items, active_item_cache::add(), active_item_cache::empty(), item_location::get_item(), submap::get_items(), item_stack::get_iterator_from_pointer(), get_submap_at(), item::needs_processing(), item_location::position(), SEEX, SEEY, submaps_with_active_items, tripoint::x, tripoint::y, and tripoint::z.

Referenced by make_active(), and liquid_handler::perform_liquid_transfer().

◆ make_rubble() [1/3]

void map::make_rubble ( const tripoint p)
inline

Definition at line 1064 of file map.h.

1064 {
1065 make_rubble( p, f_rubble, false, t_dirt, false );
1066 }

References f_rubble, make_rubble(), and t_dirt.

◆ make_rubble() [2/3]

void map::make_rubble ( const tripoint p,
const furn_id rubble_type,
bool  items 
)
inline

Definition at line 1061 of file map.h.

1061 {
1062 make_rubble( p, rubble_type, items, t_dirt, false );
1063 }

References make_rubble(), and t_dirt.

◆ make_rubble() [3/3]

void map::make_rubble ( const tripoint p,
const furn_id rubble_type,
bool  items,
const ter_id floor_type,
bool  overwrite = false 
)

Generates rubble at the given location, if overwrite is true it just writes on top of what currently exists floor_type is only used if there is a non-bashable wall at the location or with overwrite = true.

Definition at line 2509 of file map.cpp.

2511{
2512 if( overwrite ) {
2513 ter_set( p, floor_type );
2514 furn_set( p, rubble_type );
2515 } else {
2516 // First see if there is existing furniture to destroy
2517 if( is_bashable_furn( p ) ) {
2518 destroy_furn( p, true );
2519 }
2520 // Leave the terrain alone unless it interferes with furniture placement
2521 if( impassable( p ) && is_bashable_ter( p ) ) {
2522 destroy( p, true );
2523 }
2524 // Check again for new terrain after potential destruction
2525 if( impassable( p ) ) {
2526 ter_set( p, floor_type );
2527 }
2528
2529 furn_set( p, rubble_type );
2530 }
2531
2532 if( !items ) {
2533 return;
2534 }
2535
2536 //Still hardcoded, but a step up from the old stuff due to being in only one place
2537 if( rubble_type == f_wreckage ) {
2538 item chunk( "steel_chunk", calendar::turn );
2539 item scrap( "scrap", calendar::turn );
2540 add_item_or_charges( p, chunk );
2541 add_item_or_charges( p, scrap );
2542 if( one_in( 5 ) ) {
2543 item pipe( "pipe", calendar::turn );
2544 item wire( "wire", calendar::turn );
2545 add_item_or_charges( p, pipe );
2546 add_item_or_charges( p, wire );
2547 }
2548 } else if( rubble_type == f_rubble_rock ) {
2549 item rock( "rock", calendar::turn );
2550 int rock_count = rng( 1, 3 );
2551 for( int i = 0; i < rock_count; i++ ) {
2552 add_item_or_charges( p, rock );
2553 }
2554 } else if( rubble_type == f_rubble ) {
2555 item splinter( "splinter", calendar::turn );
2556 int splinter_count = rng( 2, 8 );
2557 for( int i = 0; i < splinter_count; i++ ) {
2558 add_item_or_charges( p, splinter );
2559 }
2560 spawn_item( p, itype_nail, 1, rng( 20, 50 ) );
2561 }
2562}
void destroy_furn(const tripoint &p, bool silent=false)
Keeps bashing a square until there is no more furniture.
Definition: map.cpp:3654
static const itype_id itype_nail("nail")

References add_item_or_charges(), destroy(), destroy_furn(), f_rubble, f_rubble_rock, f_wreckage, furn_set(), impassable(), is_bashable_furn(), is_bashable_ter(), itype_nail, one_in(), rng(), spawn_item(), ter_set(), and calendar::turn.

Referenced by computer_session::action_irradiator(), computer_session::action_srcf_seal(), jmapgen_make_rubble::apply(), collapse_at(), draw_lab(), draw_mine(), computer_session::failure_pump_explode(), make_rubble(), mapgen_crater(), MapExtras::mx_helicopter(), and MapExtras::mx_portal().

◆ maptile_at() [1/2]

maptile map::maptile_at ( const tripoint p)

Definition at line 210 of file map.cpp.

211{
212 if( !inbounds( p ) ) {
213 return maptile( &null_submap, point_zero );
214 }
215
216 return maptile_at_internal( p );
217}
static submap null_submap
Definition: map.cpp:199

References inbounds(), maptile_at_internal(), null_submap, and point_zero.

◆ maptile_at() [2/2]

maptile map::maptile_at ( const tripoint p) const

◆ maptile_at_internal() [1/2]

maptile map::maptile_at_internal ( const tripoint p)
private

Definition at line 227 of file map.cpp.

228{
229 point l;
230 submap *const sm = get_submap_at( p, l );
231
232 return maptile( sm, l );
233}

References get_submap_at(), and coords::sm.

◆ maptile_at_internal() [2/2]

maptile map::maptile_at_internal ( const tripoint p) const
private

Definition at line 219 of file map.cpp.

220{
221 point l;
222 submap *const sm = get_submap_at( p, l );
223
224 return maptile( sm, l );
225}

References get_submap_at(), and coords::sm.

Referenced by draw(), maptile_at(), maptile_has_bounds(), process_fields_in_submap(), route(), and spread_gas().

◆ maptile_has_bounds()

std::pair< tripoint, maptile > map::maptile_has_bounds ( const tripoint p,
bool  bounds_checked 
)
private

Definition at line 180 of file map_field.cpp.

181{
182 if( bounds_checked ) {
183 // We know that the point is in bounds
184 return {p, maptile_at_internal( p )};
185 }
186
187 return {p, maptile_at( p )};
188}

References maptile_at(), and maptile_at_internal().

Referenced by get_neighbors().

◆ max_volume()

units::volume map::max_volume ( const tripoint p)

Definition at line 4218 of file map.cpp.

4219{
4220 return i_at( p ).max_volume();
4221}
units::volume max_volume() const override
Maximum volume allowed here.
Definition: map.cpp:162

References i_at(), and map_stack::max_volume().

Referenced by advanced_inventory::print_items().

◆ mod_field_age()

time_duration map::mod_field_age ( const tripoint p,
const field_type_id type,
const time_duration offset 
)

Increment/decrement age of field entry at point.

Returns
resulting age or -1_turns if not present (does not create a new field).

Definition at line 5328 of file map.cpp.

5330{
5331 return set_field_age( p, type, offset, true );
5332}
time_duration set_field_age(const tripoint &p, const field_type_id &type, const time_duration &age, bool isoffset=false)
Set age of field entry at point.
Definition: map.cpp:5339

References set_field_age(), and type.

Referenced by game::process_artifact().

◆ mod_field_intensity()

int map::mod_field_intensity ( const tripoint p,
const field_type_id type,
int  offset 
)

Increment/decrement intensity of field entry at point, creating if not present, removing if intensity becomes 0.

Returns
resulting intensity, or 0 for not present (either removed or not created at all).

Definition at line 5334 of file map.cpp.

5335{
5336 return set_field_intensity( p, type, offset, true );
5337}
int set_field_intensity(const tripoint &p, const field_type_id &type, int new_intensity, bool isoffset=false)
Set intensity of field entry at point, creating if not present, removing if intensity becomes 0.
Definition: map.cpp:5352

References set_field_intensity(), and type.

Referenced by add_splatter(), and propagate_field().

◆ monster_in_field()

void map::monster_in_field ( monster z)
protected

Definition at line 1632 of file map_field.cpp.

1633{
1634 if( z.digging() ) {
1635 // Digging monsters are immune to fields
1636 return;
1637 }
1638 if( veh_at( z.pos() ) ) {
1639 // FIXME: Immune when in a vehicle for now.
1640 return;
1641 }
1642 field &curfield = get_field( z.pos() );
1643
1644 int dam = 0;
1645 // Iterate through all field effects on this tile.
1646 // Do not remove the field with remove_field, instead set it's intensity to 0. It will be removed
1647 // later by the field processing, which will also adjust field_count accordingly.
1648 for( auto &field_list_it : curfield ) {
1649 field_entry &cur = field_list_it.second;
1650 if( !cur.is_field_alive() ) {
1651 continue;
1652 }
1653 const field_type_id cur_field_type = cur.get_field_type();
1654 if( cur_field_type == fd_web ) {
1655 if( !z.has_flag( MF_WEBWALK ) ) {
1656 z.add_effect( effect_webbed, 1_turns, num_bp, cur.get_field_intensity() );
1657 cur.set_field_intensity( 0 );
1658 }
1659 }
1660 if( cur_field_type == fd_acid ) {
1661 if( !z.flies() ) {
1662 const int d = rng( cur.get_field_intensity(), cur.get_field_intensity() * 3 );
1663 z.deal_damage( nullptr, bodypart_id( "torso" ), damage_instance( DT_ACID, d ) );
1664 z.check_dead_state();
1665 if( d > 0 ) {
1666 z.add_effect( effect_corroding, 1_turns * rng( d / 2, d * 2 ) );
1667 }
1668 }
1669
1670 }
1671 if( cur_field_type == fd_sap ) {
1672 z.moves -= cur.get_field_intensity() * 5;
1674 }
1675 if( cur_field_type == fd_sludge ) {
1676 if( !z.digs() && !z.flies() &&
1677 !z.has_flag( MF_SLUDGEPROOF ) ) {
1678 z.moves -= cur.get_field_intensity() * 300;
1679 cur.set_field_intensity( 0 );
1680 }
1681 }
1682 if( cur_field_type == fd_fire ) {
1683 // TODO: MATERIALS Use fire resistance
1684 if( z.has_flag( MF_FIREPROOF ) || z.has_flag( MF_FIREY ) ) {
1685 return;
1686 }
1687 // TODO: Replace the section below with proper json values
1689 dam += 3;
1690 }
1691 if( z.made_of( material_id( "veggy" ) ) ) {
1692 dam += 12;
1693 }
1695 dam += 20;
1696 }
1698 dam += -20;
1699 }
1700 if( z.flies() ) {
1701 dam -= 15;
1702 }
1703 dam -= z.get_armor_type( DT_HEAT, bodypart_id( "torso" ) );
1704
1705 if( cur.get_field_intensity() == 1 ) {
1706 dam += rng( 2, 6 );
1707 } else if( cur.get_field_intensity() == 2 ) {
1708 dam += rng( 6, 12 );
1709 if( !z.flies() ) {
1710 z.moves -= 20;
1711 if( dam > 0 ) {
1712 z.add_effect( effect_onfire, 1_turns * rng( dam / 2, dam * 2 ) );
1713 }
1714 }
1715 } else if( cur.get_field_intensity() == 3 ) {
1716 dam += rng( 10, 20 );
1717 if( !z.flies() || one_in( 3 ) ) {
1718 z.moves -= 40;
1719 if( dam > 0 ) {
1720 z.add_effect( effect_onfire, 1_turns * rng( dam / 2, dam * 2 ) );
1721 }
1722 }
1723 }
1724 }
1725 if( cur_field_type == fd_smoke ) {
1726 if( !z.has_flag( MF_NO_BREATHE ) ) {
1727 if( cur.get_field_intensity() == 3 ) {
1728 z.moves -= rng( 10, 20 );
1729 }
1730 // Plants suffer from smoke even worse
1731 if( z.made_of( material_id( "veggy" ) ) ) {
1732 z.moves -= rng( 1, cur.get_field_intensity() * 12 );
1733 }
1734 }
1735
1736 }
1737 if( cur_field_type == fd_tear_gas ) {
1739 if( cur.get_field_intensity() == 3 ) {
1740 z.add_effect( effect_stunned, rng( 1_minutes, 2_minutes ) );
1741 dam += rng( 4, 10 );
1742 } else if( cur.get_field_intensity() == 2 ) {
1743 z.add_effect( effect_stunned, rng( 5_turns, 10_turns ) );
1744 dam += rng( 2, 5 );
1745 } else {
1746 z.add_effect( effect_stunned, rng( 1_turns, 5_turns ) );
1747 }
1748 if( z.made_of( material_id( "veggy" ) ) ) {
1749 z.moves -= rng( cur.get_field_intensity() * 5, cur.get_field_intensity() * 12 );
1750 dam += cur.get_field_intensity() * rng( 8, 14 );
1751 }
1752 if( z.has_flag( MF_SEES ) ) {
1753 z.add_effect( effect_blind, cur.get_field_intensity() * 8_turns );
1754 }
1755 }
1756
1757 }
1758 if( cur_field_type == fd_relax_gas ) {
1760 z.add_effect( effect_stunned, rng( cur.get_field_intensity() * 4_turns,
1761 cur.get_field_intensity() * 8_turns ) );
1762 }
1763 }
1764 if( cur_field_type == fd_dazzling ) {
1765 if( z.has_flag( MF_SEES ) && !z.has_flag( MF_ELECTRONIC ) ) {
1766 z.add_effect( effect_blind, cur.get_field_intensity() * 12_turns );
1767 z.add_effect( effect_stunned, cur.get_field_intensity() * rng( 5_turns, 12_turns ) );
1768 }
1769
1770 }
1771 if( cur_field_type == fd_toxic_gas ) {
1772 if( !z.has_flag( MF_NO_BREATHE ) ) {
1773 dam += cur.get_field_intensity();
1774 z.moves -= cur.get_field_intensity();
1775 }
1776
1777 }
1778 if( cur_field_type == fd_nuke_gas ) {
1779 if( !z.has_flag( MF_NO_BREATHE ) ) {
1780 if( cur.get_field_intensity() == 3 ) {
1781 z.moves -= rng( 60, 120 );
1782 dam += rng( 30, 50 );
1783 } else if( cur.get_field_intensity() == 2 ) {
1784 z.moves -= rng( 20, 50 );
1785 dam += rng( 10, 25 );
1786 } else {
1787 z.moves -= rng( 0, 15 );
1788 dam += rng( 0, 12 );
1789 }
1790 if( z.made_of( material_id( "veggy" ) ) ) {
1791 z.moves -= rng( cur.get_field_intensity() * 5, cur.get_field_intensity() * 12 );
1792 dam *= cur.get_field_intensity();
1793 }
1794 }
1795
1796 }
1797 if( cur_field_type == fd_flame_burst ) {
1798 // TODO: MATERIALS Use fire resistance
1799 if( z.has_flag( MF_FIREPROOF ) || z.has_flag( MF_FIREY ) ) {
1800 return;
1801 }
1803 dam += 3;
1804 }
1805 if( z.made_of( material_id( "veggy" ) ) ) {
1806 dam += 12;
1807 }
1809 dam += 50;
1810 }
1812 dam += -25;
1813 }
1814 dam += rng( 0, 8 );
1815 z.moves -= 20;
1816 }
1817 if( cur_field_type == fd_electricity ) {
1818 // We don't want to increase dam, but deal a separate hit so that it can apply effects
1819 z.deal_damage( nullptr, bodypart_id( "torso" ),
1820 damage_instance( DT_ELECTRIC, rng( 1, cur.get_field_intensity() * 3 ) ) );
1821 }
1822 if( cur_field_type == fd_fatigue ) {
1823 if( rng( 0, 2 ) < cur.get_field_intensity() ) {
1824 dam += cur.get_field_intensity();
1825 teleport::teleport( z );
1826 }
1827 }
1828 if( cur_field_type == fd_incendiary ) {
1829 // TODO: MATERIALS Use fire resistance
1830 if( z.has_flag( MF_FIREPROOF ) || z.has_flag( MF_FIREY ) ) {
1831 return;
1832 }
1834 dam += 3;
1835 }
1836 if( z.made_of( material_id( "veggy" ) ) ) {
1837 dam += 12;
1838 }
1840 dam += 20;
1841 }
1843 dam += -5;
1844 }
1845
1846 if( cur.get_field_intensity() == 1 ) {
1847 dam += rng( 2, 6 );
1848 } else if( cur.get_field_intensity() == 2 ) {
1849 dam += rng( 6, 12 );
1850 z.moves -= 20;
1851 if( !z.made_of( LIQUID ) && !z.made_of_any( Creature::cmat_flameres ) ) {
1852 z.add_effect( effect_onfire, rng( 8_turns, 12_turns ) );
1853 }
1854 } else if( cur.get_field_intensity() == 3 ) {
1855 dam += rng( 10, 20 );
1856 z.moves -= 40;
1857 if( !z.made_of( LIQUID ) && !z.made_of_any( Creature::cmat_flameres ) ) {
1858 z.add_effect( effect_onfire, rng( 12_turns, 16_turns ) );
1859 }
1860 }
1861 }
1862 if( cur_field_type == fd_fungal_haze ) {
1863 if( !z.type->in_species( FUNGUS ) &&
1864 !z.type->has_flag( MF_NO_BREATHE ) &&
1865 !z.make_fungus() ) {
1866 // Don't insta-kill jabberwocks, that's silly
1867 const int intensity = cur.get_field_intensity();
1868 z.moves -= rng( 10 * intensity, 30 * intensity );
1869 dam += rng( 0, 10 * intensity );
1870 }
1871 }
1872 if( cur_field_type == fd_fungicidal_gas ) {
1873 if( z.type->in_species( FUNGUS ) ) {
1874 const int intensity = cur.get_field_intensity();
1875 z.moves -= rng( 10 * intensity, 30 * intensity );
1876 dam += rng( 4, 7 * intensity );
1877 }
1878 }
1879 if( cur_field_type == fd_insecticidal_gas ) {
1880 if( z.type->in_species( INSECT ) || z.type->in_species( SPIDER ) ) {
1881 const int intensity = cur.get_field_intensity();
1882 z.moves -= rng( 10 * intensity, 30 * intensity );
1883 dam += rng( 4, 7 * intensity );
1884 }
1885 }
1886 }
1887
1888 if( dam > 0 ) {
1889 z.apply_damage( nullptr, bodypart_id( "torso" ), dam, true );
1890 z.check_dead_state();
1891 }
1892}
static const std::set< material_id > cmat_flammable
Definition: creature.h:477
virtual dealt_damage_instance deal_damage(Creature *source, bodypart_id bp, const damage_instance &dam)
Deals the damage via an attack.
Definition: creature.cpp:879
static const std::set< material_id > cmat_flesh
Definition: creature.h:475
int moves
Definition: creature.h:569
static const std::set< material_id > cmat_fleshnveg
Definition: creature.h:476
static const std::set< material_id > cmat_flameres
Definition: creature.h:478
bool has_flag(m_flag f) const override
Definition: monster.cpp:889
bool digs() const
Definition: monster.cpp:931
bool made_of_any(const std::set< material_id > &ms) const override
Definition: monster.cpp:983
void add_effect(const efftype_id &eff_id, const time_duration &dur, const bodypart_str_id &bp, int intensity=0, bool force=false, bool deferred=false) override
Performs any monster-specific modifications to the arguments before passing to Creature::add_effect()...
Definition: monster.cpp:1831
bool make_fungus()
Makes this monster into a fungus version Returns false if no such monster exists Returns true if mons...
Definition: monster.cpp:2623
const tripoint & pos() const override
Definition: monster.cpp:256
bool made_of(const material_id &m) const override
Definition: monster.cpp:978
const mtype * type
Definition: monster.h:481
int get_armor_type(damage_type dt, bodypart_id bp) const override
Definition: monster.cpp:1892
bool flies() const
Definition: monster.cpp:936
bool digging() const override
Definition: monster.cpp:921
@ DT_ELECTRIC
Definition: damage.h:30
@ DT_HEAT
Definition: damage.h:28
field_type_id fd_incendiary
Definition: field_type.cpp:372
field_type_id fd_toxic_gas
Definition: field_type.cpp:347
field_type_id fd_tear_gas
Definition: field_type.cpp:348
field_type_id fd_sludge
Definition: field_type.cpp:344
field_type_id fd_nuke_gas
Definition: field_type.cpp:349
field_type_id fd_dazzling
Definition: field_type.cpp:361
field_type_id fd_electricity
Definition: field_type.cpp:353
field_type_id fd_fungal_haze
Definition: field_type.cpp:374
field_type_id fd_smoke
Definition: field_type.cpp:346
field_type_id fd_sap
Definition: field_type.cpp:343
field_type_id fd_fungicidal_gas
Definition: field_type.cpp:383
field_type_id fd_acid
Definition: field_type.cpp:342
field_type_id fd_flame_burst
Definition: field_type.cpp:352
field_type_id fd_relax_gas
Definition: field_type.cpp:373
field_type_id fd_fatigue
Definition: field_type.cpp:354
field_type_id fd_insecticidal_gas
Definition: field_type.cpp:384
static const efftype_id effect_blind("blind")
static const species_id FUNGUS("FUNGUS")
static const species_id INSECT("INSECT")
static const efftype_id effect_webbed("webbed")
static const efftype_id effect_stunned("stunned")
static const species_id SPIDER("SPIDER")
static const efftype_id effect_onfire("onfire")
@ MF_SEES
Definition: mtype.h:67
@ MF_FIREY
Definition: mtype.h:103
@ MF_WEBWALK
Definition: mtype.h:85
@ MF_FIREPROOF
Definition: mtype.h:99
@ MF_SLUDGEPROOF
Definition: mtype.h:100
@ MF_ELECTRONIC
Definition: mtype.h:105
@ MF_NO_BREATHE
Definition: mtype.h:123
bool teleport(Creature &critter, int min_distance=2, int max_distance=12, bool safe=false, bool add_teleglow=true)
Teleports a creature to a tile within min_distance and max_distance tiles.
Definition: teleport.cpp:24
bool has_flag(m_flag flag) const
Definition: mtype.cpp:75
bool in_species(const species_id &spec) const
Definition: mtype.cpp:122

References monster::add_effect(), monster::apply_damage(), Creature::check_dead_state(), Creature::cmat_flameres, Creature::cmat_flammable, Creature::cmat_flesh, Creature::cmat_fleshnveg, Creature::deal_damage(), monster::digging(), monster::digs(), DT_ACID, DT_ELECTRIC, DT_HEAT, effect_blind, effect_corroding, effect_onfire, effect_stunned, effect_webbed, fd_acid, fd_dazzling, fd_electricity, fd_fatigue, fd_fire, fd_flame_burst, fd_fungal_haze, fd_fungicidal_gas, fd_incendiary, fd_insecticidal_gas, fd_nuke_gas, fd_relax_gas, fd_sap, fd_sludge, fd_smoke, fd_tear_gas, fd_toxic_gas, fd_web, monster::flies(), FUNGUS, monster::get_armor_type(), get_field(), field_entry::get_field_intensity(), field_entry::get_field_type(), monster::has_flag(), mtype::has_flag(), mtype::in_species(), INSECT, field_entry::is_field_alive(), LIQUID, monster::made_of(), monster::made_of_any(), monster::make_fungus(), MF_ELECTRONIC, MF_FIREPROOF, MF_FIREY, MF_NO_BREATHE, MF_SEES, MF_SLUDGEPROOF, MF_WEBWALK, Creature::moves, num_bp, one_in(), monster::pos(), rng(), field_entry::set_field_intensity(), SPIDER, teleport::teleport(), monster::type, and veh_at().

Referenced by creature_in_field().

◆ mop_spills()

bool map::mop_spills ( const tripoint p)

Remove moppable fields/items at this location.

Parameters
pthe location
Returns
true if anything moppable was there, false otherwise.

Definition at line 2805 of file map.cpp.

2806{
2807 bool retval = false;
2808
2809 if( !has_flag( "LIQUIDCONT", p ) && !has_flag( "SEALED", p ) ) {
2810 auto items = i_at( p );
2811 auto new_end = std::remove_if( items.begin(), items.end(), []( const item & it ) {
2812 return it.made_of( LIQUID );
2813 } );
2814 retval = new_end != items.end();
2815 while( new_end != items.end() ) {
2816 new_end = items.erase( new_end );
2817 }
2818 }
2819
2820 field &fld = field_at( p );
2821 static const std::vector<field_type_id> to_check = {
2822 fd_blood,
2830 fd_bile,
2831 fd_slime,
2832 fd_sludge
2833 };
2834 for( field_type_id fid : to_check ) {
2835 retval |= fld.remove_field( fid );
2836 }
2837
2838 if( const optional_vpart_position vp = veh_at( p ) ) {
2839 vehicle *const veh = &vp->vehicle();
2840 std::vector<int> parts_here = veh->parts_at_relative( vp->mount(), true );
2841 for( auto &elem : parts_here ) {
2842 if( veh->part( elem ).blood > 0 ) {
2843 veh->part( elem ).blood = 0;
2844 retval = true;
2845 }
2846 //remove any liquids that somehow didn't fall through to the ground
2847 vehicle_stack here = veh->get_items( elem );
2848 auto new_end = std::remove_if( here.begin(), here.end(), []( const item & it ) {
2849 return it.made_of( LIQUID );
2850 } );
2851 retval |= ( new_end != here.end() );
2852 while( new_end != here.end() ) {
2853 new_end = here.erase( new_end );
2854 }
2855 }
2856 } // if veh != 0
2857 return retval;
2858}
bool remove_field(const field_type_id &field_to_remove)
Removes the field entry with a type equal to the field_type_id parameter.
Definition: field.cpp:219
iterator erase(const_iterator it) override
Definition: vehicle.cpp:230
std::vector< int > parts_at_relative(const point &dp, bool use_cache) const
Definition: vehicle.cpp:2416
field_type_id fd_gibs_insect
Definition: field_type.cpp:365
field_type_id fd_blood_insect
Definition: field_type.cpp:363
field_type_id fd_bile
Definition: field_type.cpp:337
field_type_id fd_blood_invertebrate
Definition: field_type.cpp:364
field_type_id fd_blood_veggy
Definition: field_type.cpp:362
field_type_id fd_gibs_veggy
Definition: field_type.cpp:339
field_type_id fd_blood
Definition: field_type.cpp:336
field_type_id fd_slime
Definition: field_type.cpp:341
field_type_id fd_gibs_invertebrate
Definition: field_type.cpp:366
field_type_id fd_gibs_flesh
Definition: field_type.cpp:338

References item_stack::begin(), vehicle_part::blood, item_stack::end(), vehicle_stack::erase(), fd_bile, fd_blood, fd_blood_insect, fd_blood_invertebrate, fd_blood_veggy, fd_gibs_flesh, fd_gibs_insect, fd_gibs_invertebrate, fd_gibs_veggy, fd_slime, fd_sludge, field_at(), vehicle::get_items(), has_flag(), i_at(), vehicle::part(), vehicle::parts_at_relative(), field::remove_field(), veh_at(), and vehicle::vehicle().

◆ move_cost() [1/2]

int map::move_cost ( const point p,
const vehicle ignored_vehicle = nullptr 
) const
inline

Definition at line 623 of file map.h.

623 {
624 return move_cost( tripoint( p, abs_sub.z ), ignored_vehicle );
625 }

References abs_sub, move_cost(), and tripoint::z.

◆ move_cost() [2/2]

int map::move_cost ( const tripoint p,
const vehicle ignored_vehicle = nullptr 
) const

Calculate the cost to move past the tile at p.

The move cost is determined by various obstacles, such as terrain, vehicles and furniture.

Note
Movement costs for players and zombies both use this function.
Returns
The return value is interpreted as follows:
Move Cost Meaning
0 Impassable. Use passable/impassable to check for this.
n > 0 x*n turns to move past this

Definition at line 1780 of file map.cpp.

1781{
1782 if( !inbounds( p ) ) {
1783 return 0;
1784 }
1785
1786 const furn_t &furniture = furn( p ).obj();
1787 const ter_t &terrain = ter( p ).obj();
1788 const optional_vpart_position vp = veh_at( p );
1789 vehicle *const veh = ( !vp || &vp->vehicle() == ignored_vehicle ) ? nullptr : &vp->vehicle();
1790 const int part = veh ? vp->part_index() : -1;
1791
1792 return move_cost_internal( furniture, terrain, veh, part );
1793}
int move_cost_internal(const furn_t &furniture, const ter_t &terrain, const vehicle *veh, int vpart) const
Internal versions of public functions to avoid checking same variables multiple times.
Definition: map.cpp:1743

References furn(), furniture, inbounds(), move_cost_internal(), int_id< T >::obj(), ter(), terrain, and veh_at().

Referenced by Character::base_comfort_value(), activity_handlers::burrow_finish(), combined_movecost(), draw_mine(), game::grabbed_veh_move(), place_trap_actor::is_allowed(), is_solid_neighbor(), mine_activity(), npc::move_away_from(), move_cost(), obstacle_coverage(), passable(), activity_handlers::pickaxe_finish(), game::print_terrain_info(), reachable_flood_steps(), deploy_furn_actor::use(), game::vertical_move(), and game::walk_move().

◆ move_cost_internal()

int map::move_cost_internal ( const furn_t furniture,
const ter_t terrain,
const vehicle veh,
int  vpart 
) const
private

Internal versions of public functions to avoid checking same variables multiple times.

They lack safety checks, because their callers already do those.

Definition at line 1743 of file map.cpp.

1745{
1746 if( terrain.movecost == 0 || ( furniture.id && furniture.movecost < 0 ) ) {
1747 return 0;
1748 }
1749
1750 if( veh != nullptr ) {
1751 const vpart_position vp( const_cast<vehicle &>( *veh ), vpart );
1752 if( vp.obstacle_at_part() ) {
1753 return 0;
1754 } else if( vp.part_with_feature( VPFLAG_AISLE, true ) ) {
1755 return 2;
1756 } else {
1757 return 8;
1758 }
1759 }
1760
1761 if( furniture.id ) {
1762 return std::max( terrain.movecost + furniture.movecost, 0 );
1763 }
1764
1765 return std::max( terrain.movecost, 0 );
1766}

References furniture, vpart_position::obstacle_at_part(), vpart_position::part_with_feature(), terrain, and VPFLAG_AISLE.

Referenced by move_cost(), route(), and update_pathfinding_cache().

◆ move_cost_ter_furn() [1/2]

int map::move_cost_ter_furn ( const point p) const
inline

Definition at line 640 of file map.h.

640 {
641 return move_cost_ter_furn( tripoint( p, abs_sub.z ) );
642 }
int move_cost_ter_furn(const tripoint &p) const
Similar behavior to move_cost(), but ignores vehicles.
Definition: map.cpp:1805

References abs_sub, move_cost_ter_furn(), and tripoint::z.

◆ move_cost_ter_furn() [2/2]

int map::move_cost_ter_furn ( const tripoint p) const

Similar behavior to move_cost(), but ignores vehicles.

Definition at line 1805 of file map.cpp.

1806{
1807 if( !inbounds( p ) ) {
1808 return 0;
1809 }
1810
1811 point l;
1812 submap *const current_submap = get_submap_at( p, l );
1813
1814 const int tercost = current_submap->get_ter( l ).obj().movecost;
1815 if( tercost == 0 ) {
1816 return 0;
1817 }
1818
1819 const int furncost = current_submap->get_furn( l ).obj().movecost;
1820 if( furncost < 0 ) {
1821 return 0;
1822 }
1823
1824 const int cost = tercost + furncost;
1825 return cost > 0 ? cost : 0;
1826}

References submap::get_furn(), get_submap_at(), submap::get_ter(), inbounds(), map_data_common_t::movecost, and int_id< T >::obj().

Referenced by move_cost_ter_furn(), vehicle::part_collision(), passable_ter_furn(), and vehicle_wheel_traction().

◆ move_vehicle()

vehicle * map::move_vehicle ( vehicle veh,
const tripoint dp,
const tileray facing 
)

Definition at line 520 of file map.cpp.

521{
522 if( dp == tripoint_zero ) {
523 debugmsg( "Empty displacement vector" );
524 return &veh;
525 } else if( std::abs( dp.x ) > 1 || std::abs( dp.y ) > 1 || std::abs( dp.z ) > 1 ) {
526 debugmsg( "Invalid displacement vector: %d, %d, %d", dp.x, dp.y, dp.z );
527 return &veh;
528 }
529 // Split the movement into horizontal and vertical for easier processing
530 if( dp.xy() != point_zero && dp.z != 0 ) {
531 vehicle *const new_pointer = move_vehicle( veh, tripoint( dp.xy(), 0 ), facing );
532 if( !new_pointer ) {
533 return nullptr;
534 }
535
536 vehicle *const result = move_vehicle( *new_pointer, tripoint( 0, 0, dp.z ), facing );
537 if( !result ) {
538 return nullptr;
539 }
540
541 result->is_falling = false;
542 return result;
543 }
544 const bool vertical = dp.z != 0;
545 // Ensured by the splitting above
546 assert( vertical == ( dp.xy() == point_zero ) );
547
548 const int target_z = dp.z + veh.sm_pos.z;
549 if( target_z < -OVERMAP_DEPTH || target_z > OVERMAP_HEIGHT ) {
550 return &veh;
551 }
552
553 veh.precalc_mounts( 1, veh.skidding ? veh.turn_dir : facing.dir(), veh.pivot_point() );
554
555 // cancel out any movement of the vehicle due only to a change in pivot
556 tripoint dp1 = dp - veh.pivot_displacement();
557
558 if( !vertical ) {
559 veh.adjust_zlevel( 1, dp1 );
560 }
561
562 int impulse = 0;
563
564 std::vector<veh_collision> collisions;
565
566 // Find collisions
567 // Velocity of car before collision
568 // Split into vertical and horizontal movement
569 const int &coll_velocity = vertical ? veh.vertical_velocity : veh.velocity;
570 const int velocity_before = coll_velocity;
571 if( velocity_before == 0 && !veh.is_rotorcraft() && !veh.is_flying_in_air() ) {
572 debugmsg( "%s tried to move %s with no velocity",
573 veh.name, vertical ? "vertically" : "horizontally" );
574 return &veh;
575 }
576
577 bool veh_veh_coll_flag = false;
578 // Try to collide multiple times
579 size_t collision_attempts = 10;
580 do {
581 collisions.clear();
582 veh.collision( collisions, dp1, false );
583
584 // Vehicle collisions
585 std::map<vehicle *, std::vector<veh_collision> > veh_collisions;
586 for( auto &coll : collisions ) {
587 if( coll.type != veh_coll_veh ) {
588 continue;
589 }
590
591 veh_veh_coll_flag = true;
592 // Only collide with each vehicle once
593 veh_collisions[ static_cast<vehicle *>( coll.target ) ].push_back( coll );
594 }
595
596 for( auto &pair : veh_collisions ) {
597 impulse += vehicle_vehicle_collision( veh, *pair.first, pair.second );
598 }
599
600 // Non-vehicle collisions
601 for( const auto &coll : collisions ) {
602 if( coll.type == veh_coll_veh ) {
603 continue;
604 }
605 if( coll.part > veh.part_count() ||
606 veh.part( coll.part ).removed ) {
607 continue;
608 }
609
610 const point &collision_point = veh.part( coll.part ).mount;
611 const int coll_dmg = coll.imp;
612 // Shock damage, if the target part is a rotor treat as an aimed hit.
613 if( veh.part_info( coll.part ).rotor_diameter() > 0 ) {
614 veh.damage( coll.part, coll_dmg, DT_BASH, true );
615 } else {
616 impulse += coll_dmg;
617 veh.damage( coll.part, coll_dmg, DT_BASH );
618 veh.damage_all( coll_dmg / 2, coll_dmg, DT_BASH, collision_point );
619 }
620 }
621
622 // prevent vehicle bouncing after the first collision
623 if( vertical && velocity_before < 0 && coll_velocity > 0 ) {
624 veh.vertical_velocity = 0; // also affects `coll_velocity` and thus exits the loop
625 }
626
627 } while( collision_attempts-- > 0 && coll_velocity != 0 &&
628 sgn( coll_velocity ) == sgn( velocity_before ) &&
629 !collisions.empty() && !veh_veh_coll_flag );
630
631 const int velocity_after = coll_velocity;
632 bool can_move = velocity_after != 0 && sgn( velocity_after ) == sgn( velocity_before );
633 if( dp.z != 0 && veh.is_rotorcraft() ) {
634 can_move = true;
635 }
636 units::angle coll_turn = 0_degrees;
637 if( impulse > 0 ) {
638 coll_turn = shake_vehicle( veh, velocity_before, facing.dir() );
639 veh.stop_autodriving();
640 const int volume = std::min<int>( 100, std::sqrt( impulse ) );
641 // TODO: Center the sound at weighted (by impulse) average of collisions
643 false, "smash_success", "hit_vehicle" );
644 }
645
646 if( veh_veh_coll_flag ) {
647 // Break here to let the hit vehicle move away
648 return nullptr;
649 }
650
651 // If not enough wheels, mess up the ground a bit.
652 if( !vertical && !veh.valid_wheel_config() && !veh.is_in_water() && !veh.is_flying_in_air() &&
653 dp.z == 0 ) {
654 veh.velocity += veh.velocity < 0 ? 2000 : -2000;
655 for( const auto &p : veh.get_points() ) {
656 const ter_id &pter = ter( p );
657 if( pter == t_dirt || pter == t_grass ) {
658 ter_set( p, t_dirtmound );
659 }
660 }
661 }
662
663 const units::angle last_turn_dec = 1_degrees;
664 if( veh.last_turn < 0_degrees ) {
665 veh.last_turn += last_turn_dec;
666 if( veh.last_turn > -last_turn_dec ) {
667 veh.last_turn = 0_degrees;
668 }
669 } else if( veh.last_turn > 0_degrees ) {
670 veh.last_turn -= last_turn_dec;
671 if( veh.last_turn < last_turn_dec ) {
672 veh.last_turn = 0_degrees;
673 }
674 }
675
676 Character &player_character = get_player_character();
677 const bool seen = sees_veh( player_character, veh, false );
678
679 if( can_move || ( vertical && veh.is_falling ) ) {
680 // Accept new direction
681 if( veh.skidding ) {
682 veh.face.init( veh.turn_dir );
683 } else {
684 veh.face = facing;
685 }
686
687 veh.move = facing;
688 if( coll_turn != 0_degrees ) {
689 veh.skidding = true;
690 veh.turn( coll_turn );
691 }
692 veh.on_move();
693 // Actually change position
694 displace_vehicle( veh, dp1 );
695 veh.shift_zlevel();
696 } else if( !vertical ) {
697 veh.stop();
698 }
700 // If the PC is in the currently moved vehicle, adjust the
701 // view offset.
702 if( g->u.controlling_vehicle && veh_pointer_or_null( veh_at( g->u.pos() ) ) == &veh ) {
703 g->calc_driving_offset( &veh );
704 if( veh.skidding && can_move ) {
705 // TODO: Make skid recovery in air hard
707 }
708 }
709 // Now we're gonna handle traps we're standing on (if we're still moving).
710 if( !vertical && can_move ) {
711 const auto wheel_indices = veh.wheelcache; // Don't use a reference here, it causes a crash.
712
713 // Values to deal with crushing items.
714 // The math needs to be floating-point to work, so the values might as well be.
715 const float vehicle_grounded_wheel_area = static_cast<int>( vehicle_wheel_traction( veh, true ) );
716 const float weight_to_damage_factor = 0.05; // Nobody likes a magic number.
717 const float vehicle_mass_kg = to_kilogram( veh.total_mass() );
718
719 for( auto &w : wheel_indices ) {
720 const tripoint wheel_p = veh.global_part_pos3( w );
721 if( one_in( 2 ) && displace_water( wheel_p ) ) {
722 sounds::sound( wheel_p, 4, sounds::sound_t::movement, _( "splash!" ), false,
723 "environment", "splash" );
724 }
725
726 veh.handle_trap( wheel_p, w );
727 if( !has_flag( "SEALED", wheel_p ) ) {
728 const float wheel_area = veh.part( w ).wheel_area();
729
730 // Damage is calculated based on the weight of the vehicle,
731 // The area of it's wheels, and the area of the wheel running over the items.
732 // This number is multiplied by weight_to_damage_factor to get reasonable results, damage-wise.
733 const int wheel_damage = static_cast<int>( ( ( wheel_area / vehicle_grounded_wheel_area ) *
734 vehicle_mass_kg ) * weight_to_damage_factor );
735
736 //~ %1$s: vehicle name
737 smash_items( wheel_p, wheel_damage, string_format( _( "weight of %1$s" ), veh.disp_name() ),
738 false );
739 }
740 }
741 }
742 if( veh.is_towing() ) {
743 veh.do_towing_move();
744 // veh.do_towing_move() may cancel towing, so we need to recheck is_towing here
745 if( veh.is_towing() && veh.tow_data.get_towed()->tow_cable_too_far() ) {
746 add_msg( m_info, _( "A towing cable snaps off of %s." ),
747 veh.tow_data.get_towed()->disp_name() );
748 veh.tow_data.get_towed()->invalidate_towing( true );
749 }
750 }
751 // Redraw scene, but only if the player is not engaged in an activity and
752 // the vehicle was seen before or after the move.
753 if( !player_character.activity && ( seen || sees_veh( player_character, veh, true ) ) ) {
754 g->invalidate_main_ui_adaptor();
758 }
759 return &veh;
760}
player_activity activity
Definition: character.h:1516
float vehicle_wheel_traction(const vehicle &veh, bool ignore_movement_modifiers=false) const
void smash_items(const tripoint &p, int power, const std::string &cause_message, bool do_destroy)
Tries to smash the items at the given tripoint.
Definition: map.cpp:2994
bool displace_vehicle(vehicle &veh, const tripoint &dp)
Definition: map.cpp:1119
bool displace_water(const tripoint &dp)
Definition: map.cpp:1279
units::angle shake_vehicle(vehicle &veh, int velocity_before, units::angle direction)
vehicle * move_vehicle(vehicle &veh, const tripoint &dp, const tileray &facing)
Definition: map.cpp:520
float vehicle_vehicle_collision(vehicle &veh, vehicle &veh2, const std::vector< veh_collision > &collisions)
Definition: map.cpp:762
void init(const point &ad)
Definition: tileray.cpp:27
vehicle * get_towed() const
Definition: vehicle.h:158
void damage_all(int dmg1, int dmg2, damage_type type, const point &impact)
Definition: vehicle.cpp:6442
void turn(units::angle deg)
const point & pivot_point() const
Definition: vehicle.cpp:5826
void adjust_zlevel(int idir=0, const tripoint &offset=tripoint_zero)
bool is_rotorcraft() const
is the vehicle flying? is it a rotorcraft?
Definition: vehicle.cpp:4197
std::set< tripoint > & get_points(bool force_refresh=false)
Definition: vehicle.cpp:6758
bool skidding
Definition: vehicle.h:1999
units::angle last_turn
Definition: vehicle.h:1929
void precalc_mounts(int idir, units::angle dir, const point &pivot)
Definition: vehicle.cpp:3150
bool is_towing() const
Definition: vehicle.cpp:6034
int vertical_velocity
Definition: vehicle.h:1922
int velocity
Definition: vehicle.h:1918
bool valid_wheel_config() const
Definition: vehicle.cpp:4459
units::mass total_mass() const
Definition: vehicle.cpp:3306
std::vector< int > wheelcache
Definition: vehicle.h:1818
void check_falling_or_floating()
bool is_flying_in_air() const
Definition: vehicle.cpp:4207
towing_data tow_data
Definition: vehicle.h:1944
int damage(int p, int dmg, damage_type type=DT_BASH, bool aimed=true)
Definition: vehicle.cpp:6363
bool is_in_water(bool deep_water=false) const
is the vehicle mostly in water or mostly on fairly dry land?
Definition: vehicle.cpp:4222
void possibly_recover_from_skid()
tileray move
Definition: vehicle.h:1950
void stop_autodriving(bool apply_brakes=true)
bool collision(std::vector< veh_collision > &colls, const tripoint &dp, bool just_detect, bool bash_floor=false)
bool tow_cable_too_far() const
Definition: vehicle.cpp:6163
std::string disp_name() const
void handle_trap(const tripoint &p, int part)
bool is_falling
Definition: vehicle.h:2005
void shift_zlevel()
units::angle turn_dir
Definition: vehicle.h:1927
point pivot_displacement() const
Definition: vehicle.cpp:3344
void do_towing_move()
Definition: vehicle.cpp:5935
void on_move()
Definition: vehicle.cpp:5276
int rotor_diameter() const
Definition: veh_type.cpp:908
@ m_info
Definition: enums.h:265
constexpr int sgn(const T x)
Definition: enums.h:8
static bool sees_veh(const Creature &c, vehicle &veh, bool force_recalc)
Definition: map.cpp:512
void redraw_invalidated()
Redraw all invalidated windows without invalidating the top window.
Definition: ui_manager.cpp:394
quantity< int, volume_in_milliliter_tag > volume
Definition: units_volume.h:16
constexpr value_type to_kilogram(const quantity< value_type, mass_in_milligram_tag > &v)
Definition: units_mass.h:73
void refresh_display()
Make changes made to the display visible to the user immediately.
static constexpr tripoint tripoint_zero
Definition: point.h:273
int wheel_area() const
Get wheel diameter times wheel width (inches^2) or return 0 if part is not wheel.
bool removed
true if this part is removed.
Definition: vehicle.h:410
point mount
mount point: x is on the forward/backward axis, y is on the left/right axis
Definition: vehicle.h:367
@ veh_coll_veh
Definition: vehicle.h:101

References _, Character::activity, add_msg(), vehicle::adjust_zlevel(), vehicle::check_falling_or_floating(), vehicle::collision(), sounds::combat, vehicle::damage(), vehicle::damage_all(), debugmsg, tileray::dir(), vehicle::disp_name(), displace_vehicle(), displace_water(), vehicle::do_towing_move(), DT_BASH, vehicle::face, g, get_player_character(), vehicle::get_points(), towing_data::get_towed(), vehicle::global_part_pos3(), vehicle::global_pos3(), vehicle::handle_trap(), has_flag(), tileray::init(), inp_mngr, vehicle::invalidate_towing(), vehicle::is_falling, vehicle::is_flying_in_air(), vehicle::is_in_water(), vehicle::is_rotorcraft(), vehicle::is_towing(), vehicle::last_turn, m_info, vehicle_part::mount, vehicle::move, move_vehicle(), sounds::movement, vehicle::name, vehicle::on_move(), one_in(), OVERMAP_HEIGHT, vehicle::part(), vehicle::part_count(), vehicle::part_info(), vehicle::pivot_displacement(), vehicle::pivot_point(), point_zero, vehicle::possibly_recover_from_skid(), vehicle::precalc_mounts(), input_manager::pump_events(), ui_manager::redraw_invalidated(), refresh_display(), vehicle_part::removed, vpart_info::rotor_diameter(), sees_veh(), sgn(), shake_vehicle(), vehicle::shift_zlevel(), vehicle::skidding, vehicle::sm_pos, smash_items(), sounds::sound(), vehicle::stop(), vehicle::stop_autodriving(), string_format(), t_dirt, t_dirtmound, t_grass, ter(), ter_set(), units::to_kilogram(), vehicle::total_mass(), vehicle::tow_cable_too_far(), vehicle::tow_data, tripoint_zero, vehicle::turn(), vehicle::turn_dir, vehicle::valid_wheel_config(), veh_at(), veh_coll_veh, veh_pointer_or_null(), vehicle_vehicle_collision(), vehicle_wheel_traction(), vehicle::velocity, vehicle::vertical_velocity, vehicle_part::wheel_area(), vehicle::wheelcache, tripoint::x, tripoint::xy(), tripoint::y, and tripoint::z.

Referenced by vehicle::act_on_map(), and move_vehicle().

◆ name() [1/2]

std::string map::name ( const point p)
inline

Definition at line 839 of file map.h.

839 {
840 return name( tripoint( p, abs_sub.z ) );
841 }

References abs_sub, name(), and tripoint::z.

◆ name() [2/2]

◆ obscured_by_vehicle_rotation()

bool map::obscured_by_vehicle_rotation ( const tripoint from,
const tripoint to 
) const

Checks if a rotated vehicle is blocking diagonal vision, tripoints must be adjacent.

Definition at line 6532 of file map.cpp.

6533{
6534 if( !inbounds( from ) || !inbounds( to ) ) {
6535 return false;
6536 }
6537
6538 if( from.z != to.z ) {
6539 //Split it into two checks, one for each z level
6540 tripoint flattened = {from.xy(), to.z};
6541 if( obscured_by_vehicle_rotation( flattened, to ) ) {
6542 return true;
6543 }
6544 }
6545
6546 point delta = to.xy() - from.xy();
6547
6548 auto cache = get_cache( from.z ).vehicle_obscured_cache;
6549
6550 if( delta == point_north_west ) {
6551 return cache[from.x][from.y].nw;
6552 }
6553
6554 if( delta == point_north_east ) {
6555 return cache[from.x][from.y].ne;
6556 }
6557
6558 if( delta == point_south_west ) {
6559 return cache[to.x][to.y].ne;
6560 }
6561 if( delta == point_south_east ) {
6562 return cache[to.x][to.y].nw;
6563 }
6564
6565 return false;
6566}
bool obscured_by_vehicle_rotation(const tripoint &from, const tripoint &to) const
Checks if a rotated vehicle is blocking diagonal vision, tripoints must be adjacent.
Definition: map.cpp:6532
bool nw
Definition: map.h:297

References get_cache(), inbounds(), diagonal_blocks::nw, obscured_by_vehicle_rotation(), point_north_east, point_north_west, point_south_east, point_south_west, level_cache::vehicle_obscured_cache, tripoint::x, tripoint::xy(), tripoint::y, and tripoint::z.

Referenced by obscured_by_vehicle_rotation(), mattack::riotbot(), Creature::sees(), and sees().

◆ obstacle_coverage()

int map::obstacle_coverage ( const tripoint loc1,
const tripoint loc2 
) const

Returns coverage of target in relation to the observer.

Target is loc2, observer is loc1. First tile from the target is an obstacle, which has the coverage value. If there's no obstacle adjacent to the target - no coverage.

Definition at line 6229 of file map.cpp.

6230{
6231 // Can't hide if you are standing on furniture, or non-flat slowing-down terrain tile.
6232 if( furn( loc2 ).obj().id || ( move_cost( loc2 ) > 2 && !has_flag_ter( TFLAG_FLAT, loc2 ) ) ) {
6233 return 0;
6234 }
6235 const point a( std::abs( loc1.x - loc2.x ) * 2, std::abs( loc1.y - loc2.y ) * 2 );
6236 int offset = std::min( a.x, a.y ) - ( std::max( a.x, a.y ) / 2 );
6237 tripoint obstaclepos;
6238 bresenham( loc2, loc1, offset, 0, [&obstaclepos]( const tripoint & new_point ) {
6239 // Only adjacent tile between you and enemy is checked for cover.
6240 obstaclepos = new_point;
6241 return false;
6242 } );
6243 if( const auto obstacle_f = furn( obstaclepos ) ) {
6244 return obstacle_f->coverage;
6245 }
6246 if( const auto vp = veh_at( obstaclepos ) ) {
6247 if( vp->obstacle_at_part() ) {
6248 return 60;
6249 } else if( !vp->part_with_feature( VPFLAG_AISLE, true ) ) {
6250 return 45;
6251 }
6252 }
6253 return ter( obstaclepos )->coverage;
6254}
@ TFLAG_FLAT
Definition: mapdata.h:317

References a, bresenham(), map_data_common_t::coverage, furn(), has_flag_ter(), move_cost(), ter(), TFLAG_FLAT, veh_at(), VPFLAG_AISLE, tripoint::x, and tripoint::y.

Referenced by Creature::sees().

◆ obstacle_name()

std::string map::obstacle_name ( const tripoint p)

Returns the name of the obstacle at p that might be blocking movement/projectiles/etc.

Note that this only accounts for vehicles, terrain, and furniture.

Definition at line 1335 of file map.cpp.

1336{
1337 if( const cata::optional<vpart_reference> vp = veh_at( p ).obstacle_at_part() ) {
1338 return vp->info().name();
1339 }
1340 return name( p );
1341}

References name(), and veh_at().

Referenced by mattack::longswipe(), avatar_action::move(), and teleport::teleport().

◆ obstructed_by_vehicle_rotation()

bool map::obstructed_by_vehicle_rotation ( const tripoint from,
const tripoint to 
) const

Checks if a rotated vehicle is blocking diagonal movement, tripoints must be adjacent.

Definition at line 6495 of file map.cpp.

6496{
6497 if( !inbounds( from ) || !inbounds( to ) ) {
6498 return false;
6499 }
6500
6501 if( from.z != to.z ) {
6502 //Split it into two checks, one for each z level
6503 tripoint flattened = {from.xy(), to.z};
6504 if( obstructed_by_vehicle_rotation( flattened, to ) ) {
6505 return true;
6506 }
6507 }
6508
6509 point delta = to.xy() - from.xy();
6510
6511 auto cache = get_cache( from.z ).vehicle_obstructed_cache;
6512
6513 if( delta == point_north_west ) {
6514 return cache[from.x][from.y].nw;
6515 }
6516
6517 if( delta == point_north_east ) {
6518 return cache[from.x][from.y].ne;
6519 }
6520
6521 if( delta == point_south_west ) {
6522 return cache[to.x][to.y].ne;
6523 }
6524 if( delta == point_south_east ) {
6525 return cache[to.x][to.y].nw;
6526 }
6527
6528 return false;
6529}
diagonal_blocks vehicle_obstructed_cache[MAPSIZE_X][MAPSIZE_Y]
Definition: map.h:339

References get_cache(), inbounds(), diagonal_blocks::nw, obstructed_by_vehicle_rotation(), point_north_east, point_north_west, point_south_east, point_south_west, level_cache::vehicle_obstructed_cache, tripoint::x, tripoint::xy(), tripoint::y, and tripoint::z.

Referenced by add_splatter_trail(), mattack::boomer(), mattack::boomer_glow(), leap_actor::call(), monster::can_squeeze_to(), choose_adjacent_highlight(), clear_path(), clear_shot_reach(), explosion_handler::do_blast(), mattack::flame(), game::fling_creature(), gas_can_spread_to(), handle_action_menu(), in_spell_aoe(), game::knockback(), mattack::longswipe(), avatar_action::move(), npc::move_to(), obstructed_by_vehicle_rotation(), game::peek(), npc::pick_up_item(), process_fields_in_submap(), projectile_attack(), spell_effect::projectile_attack(), propagate_field(), mattack::ranged_pull(), player::reach_attack(), route_adjacent(), area_expander::run(), scatter_chunks(), sinkhole_safety_roll(), spell_effect::spell_effect_cone(), and test_passable().

◆ on_vehicle_moved()

void map::on_vehicle_moved ( int  smz)

Callback invoked when a vehicle has moved.

Definition at line 405 of file map.cpp.

406{
410 set_floor_cache_dirty( smz + 1 );
412}

References set_floor_cache_dirty(), set_outside_cache_dirty(), set_pathfinding_cache_dirty(), and set_transparency_cache_dirty().

Referenced by vehicle::act_on_map(), and displace_vehicle().

◆ open_door()

bool map::open_door ( const tripoint p,
bool  inside,
bool  check_only = false 
)

Definition at line 3880 of file map.cpp.

3881{
3882 const auto &ter = this->ter( p ).obj();
3883 const auto &furn = this->furn( p ).obj();
3884 if( ter.open ) {
3885 if( has_flag( "OPENCLOSE_INSIDE", p ) && !inside ) {
3886 return false;
3887 }
3888
3889 if( !check_only ) {
3890 sounds::sound( p, 6, sounds::sound_t::movement, _( "swish" ), true,
3891 "open_door", ter.id.str() );
3892 ter_set( p, ter.open );
3893
3894 if( ( g->u.has_trait( trait_id( "SCHIZOPHRENIC" ) ) || g->u.has_artifact_with( AEP_SCHIZO ) )
3895 && one_in( 50 ) && !ter.has_flag( "TRANSPARENT" ) ) {
3896 tripoint mp = p + -2 * g->u.pos().xy() + tripoint( 2 * p.x, 2 * p.y, p.z );
3897 g->spawn_hallucination( mp );
3898 }
3899 }
3900
3901 return true;
3902 } else if( furn.open ) {
3903 if( has_flag( "OPENCLOSE_INSIDE", p ) && !inside ) {
3904 return false;
3905 }
3906
3907 if( !check_only ) {
3908 sounds::sound( p, 6, sounds::sound_t::movement, _( "swish" ), true,
3909 "open_door", furn.id.str() );
3910 furn_set( p, furn.open );
3911 }
3912
3913 return true;
3914 } else if( const optional_vpart_position vp = veh_at( p ) ) {
3915 int openable = vp->vehicle().next_part_to_open( vp->part_index(), true );
3916 if( openable >= 0 ) {
3917 if( !check_only ) {
3918 if( !vp->vehicle().handle_potential_theft( dynamic_cast<player &>( g->u ) ) ) {
3919 return false;
3920 }
3921 vp->vehicle().open_all_at( openable );
3922 }
3923
3924 return true;
3925 }
3926
3927 return false;
3928 }
3929
3930 return false;
3931}
@ AEP_SCHIZO
Definition: enums.h:128

References _, AEP_SCHIZO, furn(), furn_set(), g, has_flag(), int_id< T >::id(), sounds::movement, int_id< T >::obj(), one_in(), sounds::sound(), string_id< T >::str(), ter(), ter_set(), veh_at(), tripoint::x, tripoint::y, and tripoint::z.

Referenced by can_interact_at(), npc::can_open_door(), iexamine::door_peephole(), monster::move(), avatar_action::move(), npc::move_to(), open(), and rate_location().

◆ operator=() [1/2]

map & map::operator= ( const map )
delete

◆ operator=() [2/2]

map & map::operator= ( map &&  )
default

◆ partial_con_at()

partial_con * map::partial_con_at ( const tripoint p)

Definition at line 5153 of file map.cpp.

5154{
5155 if( !inbounds( p ) ) {
5156 return nullptr;
5157 }
5158 point l;
5159 submap *const current_submap = get_submap_at( p, l );
5160 auto it = current_submap->partial_constructions.find( tripoint( l, p.z ) );
5161 if( it != current_submap->partial_constructions.end() ) {
5162 return &it->second;
5163 }
5164 return nullptr;
5165}
std::map< tripoint, partial_con > partial_constructions
Definition: submap.h:248

References get_submap_at(), inbounds(), submap::partial_constructions, and tripoint::z.

Referenced by activity_handlers::build_do_turn(), can_do_activity_there(), complete_construction(), generic_multi_activity_check_requirement(), generic_multi_activity_do(), generic_multi_activity_locations(), player_activity::get_progress_message(), place_construction(), game::print_trap_info(), and iexamine::trap().

◆ partial_con_remove()

void map::partial_con_remove ( const tripoint p)

Definition at line 5167 of file map.cpp.

5168{
5169 if( !inbounds( p ) ) {
5170 return;
5171 }
5172 point l;
5173 submap *const current_submap = get_submap_at( p, l );
5174 current_submap->partial_constructions.erase( tripoint( l, p.z ) );
5175}

References get_submap_at(), inbounds(), submap::partial_constructions, and tripoint::z.

Referenced by complete_construction(), and iexamine::trap().

◆ partial_con_set()

void map::partial_con_set ( const tripoint p,
const partial_con con 
)

Definition at line 5177 of file map.cpp.

5178{
5179 if( !inbounds( p ) ) {
5180 return;
5181 }
5182 point l;
5183 submap *const current_submap = get_submap_at( p, l );
5184 if( !current_submap->partial_constructions.emplace( tripoint( l, p.z ), con ).second ) {
5185 debugmsg( "set partial con on top of terrain which already has a partial con" );
5186 }
5187}

References debugmsg, get_submap_at(), inbounds(), submap::partial_constructions, and tripoint::z.

Referenced by construction_activity(), and place_construction().

◆ passable() [1/2]

bool map::passable ( const point p) const
inline

Definition at line 631 of file map.h.

631 {
632 return passable( tripoint( p, abs_sub.z ) );
633 }

References abs_sub, passable(), and tripoint::z.

◆ passable() [2/2]

◆ passable_ter_furn()

bool map::passable_ter_furn ( const tripoint p) const

Definition at line 1833 of file map.cpp.

1834{
1835 return move_cost_ter_furn( p ) != 0;
1836}

References move_cost_ter_furn().

Referenced by impassable_ter_furn(), and avatar_action::move().

◆ pl_line_of_sight()

bool map::pl_line_of_sight ( const tripoint t,
int  max_range 
) const

Uses the map cache to tell if the player could see the given square.

pl_sees implies pl_line_of_sight Used for infrared.

Definition at line 795 of file lightmap.cpp.

796{
797 if( !inbounds( t ) ) {
798 return false;
799 }
800
801 if( max_range >= 0 && square_dist( t, g->u.pos() ) > max_range ) {
802 // Out of range!
803 return false;
804 }
805
806 const auto &map_cache = get_cache_ref( t.z );
807 // Any epsilon > 0 is fine - it means lightmap processing visited the point
808 return map_cache.seen_cache[t.x][t.y] > 0.0f ||
809 map_cache.camera_cache[t.x][t.y] > 0.0f;
810}

References g, get_cache_ref(), inbounds(), square_dist(), tripoint::x, tripoint::y, and tripoint::z.

Referenced by get_heat_radiation(), and Character::sees_with_infrared().

◆ pl_sees()

bool map::pl_sees ( const tripoint t,
int  max_range 
) const

Whether the player character (g->u) can see the given square (local map coordinates).

This only checks the transparency of the path to the target, the light level is not checked.

Parameters
tTarget point to look at
max_rangeAll squares that are further away than this are invisible. Ignored if smaller than 0.

Definition at line 777 of file lightmap.cpp.

778{
779 if( !inbounds( t ) ) {
780 return false;
781 }
782
783 if( max_range >= 0 && square_dist( t, g->u.pos() ) > max_range ) {
784 return false; // Out of range!
785 }
786
787 const auto &map_cache = get_cache_ref( t.z );
788 const apparent_light_info a = apparent_light_helper( map_cache, t );
789 const float light_at_player = map_cache.lm[g->u.posx()][g->u.posy()].max();
790 return !a.obstructed &&
791 ( a.apparent_light >= g->u.get_vision_threshold( light_at_player ) ||
792 map_cache.sm[t.x][t.y] > 0.0 );
793}

References a, apparent_light_helper(), g, get_cache_ref(), inbounds(), square_dist(), tripoint::x, tripoint::y, and tripoint::z.

Referenced by computer_session::action_irradiator(), sounds::process_sound_markers(), and Character::sees().

◆ place_gas_pump() [1/2]

void map::place_gas_pump ( const point p,
int  charges 
)

Definition at line 5454 of file mapgen.cpp.

5455{
5456 place_gas_pump( p, charges, one_in( 4 ) ? "diesel" : "gasoline" );
5457}
void place_gas_pump(const point &p, int charges, const std::string &fuel_type)
Definition: mapgen.cpp:5446

References one_in(), and place_gas_pump().

◆ place_gas_pump() [2/2]

void map::place_gas_pump ( const point p,
int  charges,
const std::string &  fuel_type 
)

Definition at line 5446 of file mapgen.cpp.

5447{
5448 item fuel( fuel_type, calendar::start_of_cataclysm );
5449 fuel.charges = charges;
5450 add_item( p, fuel );
5451 ter_set( p, ter_id( fuel.fuel_pump_terrain() ) );
5452}

References add_item(), item::charges, item::fuel_pump_terrain(), calendar::start_of_cataclysm, ter_id, and ter_set().

Referenced by jmapgen_gaspump::apply(), mapgen_tutorial(), and place_gas_pump().

◆ place_items() [1/2]

std::vector< item * > map::place_items ( const item_group_id loc,
int  chance,
const point p1,
const point p2,
bool  ongrass,
const time_point turn,
int  magazine = 0,
int  ammo = 0 
)
inline

Definition at line 1367 of file map.h.

1369 {
1370 return place_items( loc, chance, tripoint( p1, abs_sub.z ), tripoint( p2, abs_sub.z ), ongrass,
1371 turn, magazine, ammo );
1372 }

References abs_sub, place_items(), calendar::turn, and tripoint::z.

◆ place_items() [2/2]

std::vector< item * > map::place_items ( const item_group_id loc,
int  chance,
const tripoint p1,
const tripoint p2,
bool  ongrass,
const time_point turn,
int  magazine = 0,
int  ammo = 0 
)

Place items from item group in the rectangle f - t.

Several items may be spawned on different places. Several items may spawn at once (at one place) when the item group says so (uses item_group::items_from which may return several items at once).

Parameters
locCurrent location of items to be placed
chanceChance for more items. A chance of 100 creates 1 item all the time, otherwise it's the chance that more items will be created (place items until the random roll with that chance fails). The chance is used for the first item as well, so it may not spawn an item at all. Values <= 0 or > 100 are invalid.
p1One corner of rectangle in which to spawn items
p2Second corner of rectangle in which to spawn items
ongrassIf false the items won't spawn on flat terrain (grass, floor, ...).
turnThe birthday that the created items shall have.
magazinepercentage chance item will contain the default magazine
ammopercentage chance item will be filled with default ammo
Returns
vector containing all placed items

Definition at line 5520 of file mapgen.cpp.

5524{
5525 // TODO: implement for 3D
5526 std::vector<item *> res;
5527
5528 if( chance > 100 || chance <= 0 ) {
5529 debugmsg( "map::place_items() called with an invalid chance (%d)", chance );
5530 return res;
5531 }
5532 if( !item_group::group_is_defined( loc ) ) {
5533 // TODO: fix point types
5535 const oter_id &oid = overmap_buffer.ter( omt );
5536 debugmsg( "place_items: invalid item group '%s', om_terrain = '%s' (%s)",
5537 loc.c_str(), oid.id().c_str(), oid->get_mapgen_id().c_str() );
5538 return res;
5539 }
5540
5541 const float spawn_rate = get_option<float>( "ITEM_SPAWNRATE" );
5542 int spawn_count = roll_remainder( chance * spawn_rate / 100.0f );
5543 for( int i = 0; i < spawn_count; i++ ) {
5544 // Might contain one item or several that belong together like guns & their ammo
5545 int tries = 0;
5546 auto is_valid_terrain = [this, ongrass]( const point & p ) {
5547 auto &terrain = ter( p ).obj();
5548 return terrain.movecost == 0 &&
5549 !terrain.has_flag( "PLACE_ITEM" ) &&
5550 !ongrass &&
5551 !terrain.has_flag( "FLAT" );
5552 };
5553
5554 point p;
5555 do {
5556 p.x = rng( p1.x, p2.x );
5557 p.y = rng( p1.y, p2.y );
5558 tries++;
5559 } while( is_valid_terrain( p ) && tries < 20 );
5560 if( tries < 20 ) {
5561 auto put = put_items_from_loc( loc, tripoint( p, abs_sub.z ), turn );
5562 res.insert( res.end(), put.begin(), put.end() );
5563 }
5564 }
5565 for( auto e : res ) {
5566 if( e->is_tool() || e->is_gun() || e->is_magazine() ) {
5567 if( rng( 0, 99 ) < magazine && !e->magazine_integral() && !e->magazine_current() ) {
5568 e->put_in( item( e->magazine_default(), e->birthday() ) );
5569 }
5570 if( rng( 0, 99 ) < ammo && e->ammo_remaining() == 0 ) {
5571 e->ammo_set( e->ammo_default(), e->ammo_capacity() );
5572 }
5573 }
5574 }
5575 return res;
5576}
constexpr scale omt
Definition: coordinates.h:32
bool group_is_defined(const item_group_id &group_id)
Check whether an item group of the given id exists.
Definition: item_group.cpp:603

References abs_sub, string_id< T >::c_str(), debugmsg, get_abs_sub(), oter_t::get_mapgen_id(), item_group::group_is_defined(), int_id< T >::id(), int_id< T >::obj(), coords::omt, overmap_buffer, put_items_from_loc(), rng(), roll_remainder(), sm_to_omt_copy(), ter(), overmapbuffer::ter(), terrain, calendar::turn, point::x, tripoint::x, point::y, tripoint::y, and tripoint::z.

Referenced by jmapgen_item_group::apply(), draw_lab(), draw_mine(), draw_office_tower(), draw_slimepit(), mapgen_ants_food(), mapgen_ants_generic(), mapgen_ants_larvae(), mapgen_ants_queen(), mapgen_cavern(), mapgen_crater(), mapgen_field(), mapgen_forest(), mapgen_forest_trail_curved(), mapgen_forest_trail_four_way(), mapgen_forest_trail_straight(), mapgen_forest_trail_tee(), mapgen_highway(), mapgen_hive(), mapgen_parking_lot(), mapgen_road(), mapgen_sewer_curved(), mapgen_sewer_four_way(), mapgen_sewer_straight(), mapgen_sewer_tee(), MapExtras::mx_collegekids(), MapExtras::mx_drugdeal(), MapExtras::mx_house_spider(), MapExtras::mx_house_wasp(), MapExtras::mx_military(), MapExtras::mx_minefield(), MapExtras::mx_roadblock(), MapExtras::mx_roadworks(), MapExtras::mx_science(), MapExtras::mx_supplydrop(), place_items(), place_vending(), mission_start::ranch_nurse_8(), mission_start::ranch_scavenger_1(), mission_start::ranch_scavenger_2(), mission_start::ranch_scavenger_3(), and science_room().

◆ place_npc()

character_id map::place_npc ( const point p,
const string_id< npc_template > &  type,
bool  force = false 
)

Definition at line 5487 of file mapgen.cpp.

5488{
5489 if( !force && !get_option<bool>( "STATIC_NPC" ) ) {
5490 return character_id(); //Do not generate an npc.
5491 }
5492 shared_ptr_fast<npc> temp = make_shared_fast<npc>();
5493 temp->normalize();
5494 temp->load_npc_template( type );
5495 temp->spawn_at_precise( { abs_sub.xy() }, { p, abs_sub.z } );
5496 temp->toggle_trait( trait_NPC_STATIC_NPC );
5497 overmap_buffer.insert_npc( temp );
5498 return temp->getID();
5499}
void insert_npc(const shared_ptr_fast< npc > &who)
Adds the npc to an overmap ( based on the npcs current location ) and stores it there.
static const trait_id trait_NPC_STATIC_NPC("NPC_STATIC_NPC")
std::shared_ptr< T > shared_ptr_fast
Definition: memory_fast.h:16

References abs_sub, character_id, overmapbuffer::insert_npc(), overmap_buffer, trait_NPC_STATIC_NPC, type, tripoint::xy(), and tripoint::z.

Referenced by jmapgen_npc::apply(), mapgen_hive(), MapExtras::mx_bandits_block(), MapExtras::mx_looters(), MapExtras::mx_marloss_pilgrimage(), mission_start::ranch_nurse_9(), and place_npc_iuse::use().

◆ place_spawns()

void map::place_spawns ( const mongroup_id group,
int  chance,
const point p1,
const point p2,
float  density,
bool  individual = false,
bool  friendly = false,
const std::string &  name = "NONE",
int  mission_id = -1 
)

Definition at line 5396 of file mapgen.cpp.

5399{
5400 if( !group.is_valid() ) {
5401 // TODO: fix point types
5403 const oter_id &oid = overmap_buffer.ter( omt );
5404 debugmsg( "place_spawns: invalid mongroup '%s', om_terrain = '%s' (%s)", group.c_str(),
5405 oid.id().c_str(), oid->get_mapgen_id().c_str() );
5406 return;
5407 }
5408
5409 // Set chance to be 1 or less to guarantee spawn, else set higher than 1
5410 if( !one_in( chance ) ) {
5411 return;
5412 }
5413
5414 float spawn_density = 1.0f;
5416 spawn_density = get_option< float >( "SPAWN_ANIMAL_DENSITY" );
5417 } else {
5418 spawn_density = get_option< float >( "SPAWN_DENSITY" );
5419 }
5420
5421 float multiplier = density * spawn_density;
5422 // Only spawn 1 creature if individual flag set, else scale by density
5423 float thenum = individual ? 1 : ( multiplier * rng_float( 10.0f, 50.0f ) );
5424 int num = roll_remainder( thenum );
5425
5426 // GetResultFromGroup decrements num
5427 while( num > 0 ) {
5428 int tries = 10;
5429 point p;
5430
5431 // Pick a spot for the spawn
5432 do {
5433 p.x = rng( p1.x, p2.x );
5434 p.y = rng( p1.y, p2.y );
5435 tries--;
5436 } while( impassable( p ) && tries > 0 );
5437
5438 // Pick a monster type
5440
5441 add_spawn( spawn_details.name, spawn_details.pack_size, { p, abs_sub.z },
5442 friendly, -1, mission_id, name );
5443 }
5444}
group
Definition: sounds.h:125

References add_spawn(), string_id< T >::c_str(), debugmsg, friendly, get_abs_sub(), oter_t::get_mapgen_id(), MonsterGroupManager::GetResultFromGroup(), int_id< T >::id(), impassable(), MonsterGroupManager::is_animal(), name(), MonsterGroupResult::name, num, coords::omt, one_in(), overmap_buffer, MonsterGroupResult::pack_size, rng(), rng_float(), roll_remainder(), sm_to_omt_copy(), overmapbuffer::ter(), point::x, and point::y.

Referenced by add_monsters(), jmapgen_monster_group::apply(), create_anomaly(), draw_lab(), draw_mine(), draw_office_tower(), draw_slimepit(), draw_temple(), draw_triffid(), mapgen_road(), MapExtras::mx_collegekids(), MapExtras::mx_corpses(), MapExtras::mx_drugdeal(), MapExtras::mx_military(), MapExtras::mx_pond(), MapExtras::mx_portal(), MapExtras::mx_portal_in(), MapExtras::mx_science(), and science_room().

◆ place_toilet()

void map::place_toilet ( const point p,
int  charges = 6 * 4 
)

Definition at line 5459 of file mapgen.cpp.

5460{
5461 item water( "water", calendar::start_of_cataclysm );
5462 water.charges = charges;
5463 add_item( p, water );
5464 furn_set( p, f_toilet );
5465}

References add_item(), item::charges, f_toilet, furn_set(), and calendar::start_of_cataclysm.

Referenced by jmapgen_toilet::apply(), and mapf::formatted_set_simple().

◆ place_vending()

void map::place_vending ( const point p,
const item_group_id type,
bool  reinforced = false 
)

Definition at line 5467 of file mapgen.cpp.

5468{
5469 if( reinforced ) {
5471 place_items( type, 100, p, p, false, calendar::start_of_cataclysm );
5472 } else {
5473 if( one_in( 2 ) ) {
5474 furn_set( p, f_vending_o );
5475 for( const auto &loc : points_in_radius( { p, abs_sub.z }, 1 ) ) {
5476 if( one_in( 4 ) ) {
5477 spawn_item( loc, "glass_shard", rng( 1, 2 ) );
5478 }
5479 }
5480 } else {
5481 furn_set( p, f_vending_c );
5482 place_items( type, 100, p, p, false, calendar::start_of_cataclysm );
5483 }
5484 }
5485}
furn_id f_vending_o
Definition: mapdata.cpp:1109
furn_id f_vending_reinforced
Definition: mapdata.cpp:1132
furn_id f_vending_c
Definition: mapdata.cpp:1109

References abs_sub, f_vending_c, f_vending_o, f_vending_reinforced, furn_set(), one_in(), place_items(), points_in_radius(), rng(), spawn_item(), calendar::start_of_cataclysm, type, and tripoint::z.

Referenced by jmapgen_vending_machine::apply().

◆ player_in_field()

void map::player_in_field ( player u)
protected

Definition at line 1224 of file map_field.cpp.

1225{
1226 // A copy of the current field for reference. Do not add fields to it, use map::add_field
1227 field &curfield = get_field( u.pos() );
1228 // Are we inside?
1229 bool inside = false;
1230 // If we are in a vehicle figure out if we are inside (reduces effects usually)
1231 // and what part of the vehicle we need to deal with.
1232 if( u.in_vehicle ) {
1233 if( const optional_vpart_position vp = veh_at( u.pos() ) ) {
1234 inside = vp->is_inside();
1235 }
1236 }
1237
1238 // Iterate through all field effects on this tile.
1239 // Do not remove the field with remove_field, instead set it's intensity to 0. It will be removed
1240 // later by the field processing, which will also adjust field_count accordingly.
1241 for( auto &field_list_it : curfield ) {
1242 field_entry &cur = field_list_it.second;
1243 if( !cur.is_field_alive() ) {
1244 continue;
1245 }
1246
1247 // Do things based on what field effect we are currently in.
1248 const field_type_id ft = cur.get_field_type();
1249 if( ft == fd_web ) {
1250 // If we are in a web, can't walk in webs or are in a vehicle, get webbed maybe.
1251 // Moving through multiple webs stacks the effect.
1252 if( !u.has_trait( trait_WEB_WALKER ) && !u.in_vehicle ) {
1253 // Between 5 and 15 minus your current web level.
1254 u.add_effect( effect_webbed, 1_turns, num_bp, cur.get_field_intensity() );
1255 // It is spent.
1256 cur.set_field_intensity( 0 );
1257 continue;
1258 // If you are in a vehicle destroy the web.
1259 // It should of been destroyed when you ran over it anyway.
1260 } else if( u.in_vehicle ) {
1261 cur.set_field_intensity( 0 );
1262 continue;
1263 }
1264 }
1265 if( ft == fd_acid ) {
1266 // Assume vehicles block acid damage entirely,
1267 // you're certainly not standing in it.
1268 if( !u.in_vehicle && !u.has_trait( trait_ACIDPROOF ) ) {
1269 int total_damage = 0;
1270 total_damage += burn_body_part( u, cur, bp_foot_l, 2 );
1271 total_damage += burn_body_part( u, cur, bp_foot_r, 2 );
1272 const bool on_ground = u.is_on_ground();
1273 if( on_ground ) {
1274 // Apply the effect to the remaining body parts
1275 total_damage += burn_body_part( u, cur, bp_leg_l, 2 );
1276 total_damage += burn_body_part( u, cur, bp_leg_r, 2 );
1277 total_damage += burn_body_part( u, cur, bp_hand_l, 2 );
1278 total_damage += burn_body_part( u, cur, bp_hand_r, 2 );
1279 total_damage += burn_body_part( u, cur, bp_torso, 2 );
1280 // Less arms = less ability to keep upright
1281 if( ( !u.has_two_arms() && one_in( 4 ) ) || one_in( 2 ) ) {
1282 total_damage += burn_body_part( u, cur, bp_arm_l, 1 );
1283 total_damage += burn_body_part( u, cur, bp_arm_r, 1 );
1284 total_damage += burn_body_part( u, cur, bp_head, 1 );
1285 }
1286 }
1287
1288 if( on_ground && total_damage > 0 ) {
1289 u.add_msg_player_or_npc( m_bad, _( "The acid burns your body!" ),
1290 _( "The acid burns <npcname>s body!" ) );
1291 } else if( total_damage > 0 ) {
1292 u.add_msg_player_or_npc( m_bad, _( "The acid burns your legs and feet!" ),
1293 _( "The acid burns <npcname>s legs and feet!" ) );
1294 } else if( on_ground ) {
1295 u.add_msg_if_player( m_warning, _( "You're lying in a pool of acid" ) );
1296 } else {
1297 u.add_msg_if_player( m_warning, _( "You're standing in a pool of acid" ) );
1298 }
1299
1300 u.check_dead_state();
1301 }
1302 }
1303 if( ft == fd_sap ) {
1304 // Sap does nothing to cars.
1305 if( !u.in_vehicle ) {
1306 // Use up sap.
1308 }
1309 }
1310 if( ft == fd_sludge ) {
1311 // Sludge is on the ground, but you are above the ground when boarded on a vehicle
1312 if( !u.in_vehicle ) {
1313 u.add_msg_if_player( m_bad, _( "The sludge is thick and sticky. You struggle to pull free." ) );
1314 u.moves -= cur.get_field_intensity() * 300;
1315 cur.set_field_intensity( 0 );
1316 }
1317 }
1318 if( ft == fd_fire ) {
1319 // Heatsink or suit prevents ALL fire damage.
1321
1322 // To modify power of a field based on... whatever is relevant for the effect.
1323 int adjusted_intensity = cur.get_field_intensity();
1324 // Burn the player. Less so if you are in a car or ON a car.
1325 if( u.in_vehicle ) {
1326 if( inside ) {
1327 adjusted_intensity -= 2;
1328 } else {
1329 adjusted_intensity -= 1;
1330 }
1331 }
1332
1333 if( adjusted_intensity >= 1 ) {
1334 // Burn message by intensity
1335 static const std::array<std::string, 4> player_burn_msg = { {
1336 translate_marker( "You burn your legs and feet!" ),
1337 translate_marker( "You're burning up!" ),
1338 translate_marker( "You're set ablaze!" ),
1339 translate_marker( "Your whole body is burning!" )
1340 }
1341 };
1342 static const std::array<std::string, 4> npc_burn_msg = { {
1343 translate_marker( "<npcname> burns their legs and feet!" ),
1344 translate_marker( "<npcname> is burning up!" ),
1345 translate_marker( "<npcname> is set ablaze!" ),
1346 translate_marker( "<npcname>s whole body is burning!" )
1347 }
1348 };
1349 static const std::array<std::string, 4> player_warn_msg = { {
1350 translate_marker( "You're standing in a fire!" ),
1351 translate_marker( "You're waist-deep in a fire!" ),
1352 translate_marker( "You're surrounded by raging fire!" ),
1353 translate_marker( "You're lying in fire!" )
1354 }
1355 };
1356
1357 const int burn_min = adjusted_intensity;
1358 const int burn_max = 3 * adjusted_intensity + 3;
1359 std::list<bodypart_id> parts_burned;
1360 int msg_num = adjusted_intensity - 1;
1361 if( !u.is_on_ground() ) {
1362 switch( adjusted_intensity ) {
1363 case 3:
1364 parts_burned.push_back( bodypart_id( "hand_l" ) );
1365 parts_burned.push_back( bodypart_id( "hand_r" ) );
1366 parts_burned.push_back( bodypart_id( "arm_l" ) );
1367 parts_burned.push_back( bodypart_id( "arm_r" ) );
1368 /* fallthrough */
1369 case 2:
1370 parts_burned.push_back( bodypart_id( "torso" ) );
1371 /* fallthrough */
1372 case 1:
1373 parts_burned.push_back( bodypart_id( "foot_l" ) );
1374 parts_burned.push_back( bodypart_id( "foot_r" ) );
1375 parts_burned.push_back( bodypart_id( "leg_l" ) );
1376 parts_burned.push_back( bodypart_id( "leg_r" ) );
1377 }
1378 } else {
1379 // Lying in the fire is BAAAD news, hits every body part.
1380 msg_num = 3;
1381 const std::vector<bodypart_id> &all_parts = u.get_all_body_parts();
1382 // HACK: Skip num_bp part
1383 for( auto bp : all_parts ) {
1384 if( bp->token != num_bp ) {
1385 parts_burned.push_back( bp );
1386 }
1387 }
1388 }
1389
1390 int total_damage = 0;
1391 for( const bodypart_id part_burned : parts_burned ) {
1392 const dealt_damage_instance dealt = u.deal_damage( nullptr, part_burned,
1393 damage_instance( DT_HEAT, rng( burn_min, burn_max ) ) );
1394 total_damage += dealt.type_damage( DT_HEAT );
1395 }
1396 if( total_damage > 0 ) {
1397 u.add_msg_player_or_npc( m_bad, _( player_burn_msg[msg_num] ), _( npc_burn_msg[msg_num] ) );
1398 } else {
1399 u.add_msg_if_player( m_warning, _( player_warn_msg[msg_num] ) );
1400 }
1401 u.check_dead_state();
1402 }
1403 }
1404
1405 }
1406 if( ft == fd_tear_gas ) {
1407 // Tear gas will both give you teargas disease and/or blind you.
1408 if( ( cur.get_field_intensity() > 1 || !one_in( 3 ) ) && ( !inside || one_in( 3 ) ) ) {
1409 u.add_env_effect( effect_teargas, bp_mouth, 5, 20_seconds );
1410 }
1411 if( cur.get_field_intensity() > 1 && ( !inside || one_in( 3 ) ) ) {
1412 u.add_env_effect( effect_blind, bp_eyes, cur.get_field_intensity() * 2, 10_seconds );
1413 }
1414 }
1415 if( ft == fd_fungal_haze ) {
1416 if( !u.has_trait( trait_M_IMMUNE ) && ( !inside || one_in( 4 ) ) ) {
1417 u.add_env_effect( effect_fungus, bp_mouth, 4, 10_minutes, num_bp );
1418 u.add_env_effect( effect_fungus, bp_eyes, 4, 10_minutes, num_bp );
1419 }
1420 }
1421 if( ft == fd_dazzling ) {
1422 if( cur.get_field_intensity() > 1 || one_in( 5 ) ) {
1423 u.add_env_effect( effect_blind, bp_eyes, 10, 10_turns );
1424 } else {
1425 u.add_env_effect( effect_blind, bp_eyes, 2, 2_turns );
1426 }
1427 }
1428
1429 if( cur.extra_radiation_min() > 0 ) {
1430 // Get irradiated by the nuclear fallout.
1431 const float rads = rng( cur.extra_radiation_min() + 1,
1432 cur.extra_radiation_max() * ( cur.extra_radiation_max() + 1 ) );
1433 const bool rad_proof = !u.irradiate( rads );
1434 // TODO: Reduce damage for rad resistant?
1435 if( cur.radiation_hurt_damage_min() > 0 && !rad_proof ) {
1437 u.hurtall( rng( cur.radiation_hurt_damage_min(), cur.radiation_hurt_damage_max() ), nullptr );
1438 }
1439 }
1440 if( ft == fd_flame_burst ) {
1441 // A burst of flame? Only hits the legs and torso.
1442 if( !inside ) {
1443 // Fireballs can't touch you inside a car.
1444 // Heatsink or suit stops fire.
1445 if( !u.has_active_bionic( bio_heatsink ) &&
1447 u.add_msg_player_or_npc( m_bad, _( "You're torched by flames!" ),
1448 _( "<npcname> is torched by flames!" ) );
1449 u.deal_damage( nullptr, bodypart_id( "leg_l" ), damage_instance( DT_HEAT, rng( 2, 6 ) ) );
1450 u.deal_damage( nullptr, bodypart_id( "leg_r" ), damage_instance( DT_HEAT, rng( 2, 6 ) ) );
1451 u.deal_damage( nullptr, bodypart_id( "torso" ), damage_instance( DT_HEAT, rng( 4, 9 ) ) );
1452 u.check_dead_state();
1453 } else {
1454 u.add_msg_player_or_npc( _( "These flames do not burn you." ),
1455 _( "Those flames do not burn <npcname>." ) );
1456 }
1457 }
1458 }
1459 if( ft == fd_electricity ) {
1460 // Small universal damage based on intensity, only if not electroproofed.
1461 if( !u.is_elec_immune() ) {
1462 int total_damage = 0;
1463 for( size_t i = 0; i < num_hp_parts; i++ ) {
1464 const bodypart_id bp = convert_bp( player::hp_to_bp( static_cast<hp_part>( i ) ) ).id();
1465 const int dmg = rng( 1, cur.get_field_intensity() );
1466 total_damage += u.deal_damage( nullptr, bp, damage_instance( DT_ELECTRIC, dmg ) ).total_damage();
1467 }
1468
1469 if( total_damage > 0 ) {
1471 u.add_msg_player_or_npc( m_bad, _( "You're painfully electrocuted!" ),
1472 _( "<npcname> is shocked!" ) );
1473 u.mod_pain( total_damage / 2 );
1474 } else {
1475 u.add_msg_player_or_npc( m_bad, _( "You're shocked!" ), _( "<npcname> is shocked!" ) );
1476 }
1477 } else {
1478 u.add_msg_player_or_npc( _( "The electric cloud doesn't affect you." ),
1479 _( "The electric cloud doesn't seem to affect <npcname>." ) );
1480 }
1481 }
1482 }
1483 if( ft == fd_fatigue ) {
1484 // Assume the rift is on the ground for now to prevent issues with the player being unable access vehicle controls on the same tile due to teleportation.
1485 if( !u.in_vehicle ) {
1486 // Teleports you... somewhere.
1487 if( rng( 0, 2 ) < cur.get_field_intensity() && u.is_player() ) {
1488 add_msg( m_bad, _( "You're violently teleported!" ) );
1489 u.hurtall( cur.get_field_intensity(), nullptr );
1490 teleport::teleport( u );
1491 }
1492 }
1493 }
1494 // Why do these get removed???
1495 // Stepping on a shock vent shuts it down.
1496 if( ft == fd_shock_vent || ft == fd_acid_vent ) {
1497 cur.set_field_intensity( 0 );
1498 }
1499 if( ft == fd_bees ) {
1500 // Player is immune to bees while underwater.
1501 if( !u.is_underwater() ) {
1502 const int intensity = cur.get_field_intensity();
1503 // Bees will try to sting you in random body parts, up to 8 times.
1504 for( int i = 0; i < rng( 1, 7 ); i++ ) {
1506 int sum_cover = 0;
1507 for( const item &i : u.worn ) {
1508 if( i.covers( bp->token ) ) {
1509 sum_cover += i.get_coverage();
1510 }
1511 }
1512 // Get stung if [clothing on a body part isn't thick enough (like t-shirt) OR clothing covers less than 100% of body part]
1513 // AND clothing on affected body part has low environmental protection value
1514 if( ( u.get_armor_cut( bp ) <= 1 || ( sum_cover < 100 && x_in_y( 100 - sum_cover, 100 ) ) ) &&
1515 u.add_env_effect( effect_stung, bp->token, intensity, 9_minutes ) ) {
1516 u.add_msg_if_player( m_bad, _( "The bees sting you in %s!" ),
1517 body_part_name_accusative( bp->token ) );
1518 }
1519 }
1520 }
1521 }
1522 if( ft == fd_incendiary ) {
1523 // Mysterious incendiary substance melts you horribly.
1524 if( u.has_trait( trait_M_SKIN2 ) ||
1525 u.has_trait( trait_M_SKIN3 ) ||
1526 cur.get_field_intensity() == 1 ) {
1527 u.add_msg_player_or_npc( m_bad, _( "The incendiary burns you!" ),
1528 _( "The incendiary burns <npcname>!" ) );
1529 u.hurtall( rng( 1, 3 ), nullptr );
1530 } else {
1531 u.add_msg_player_or_npc( m_bad, _( "The incendiary melts into your skin!" ),
1532 _( "The incendiary melts into <npcname>s skin!" ) );
1533 u.add_effect( effect_onfire, 8_turns, bp_torso );
1534 u.hurtall( rng( 2, 6 ), nullptr );
1535 }
1536 }
1537 // Both gases are unhealthy and become deadly if you cross a related threshold.
1538 if( ft == fd_fungicidal_gas || ft == fd_insecticidal_gas ) {
1539 // The gas won't harm you inside a vehicle.
1540 if( !inside ) {
1541 // Full body suits protect you from the effects of the gas.
1542 if( !( u.worn_with_flag( flag_GAS_PROOF ) && u.get_env_resist( bodypart_id( "mouth" ) ) >= 15 &&
1543 u.get_env_resist( bodypart_id( "eyes" ) ) >= 15 ) ) {
1544 const int intensity = cur.get_field_intensity();
1545 bool inhaled = u.add_env_effect( effect_poison, bp_mouth, 5, intensity * 1_minutes );
1547 ( ft == fd_insecticidal_gas && ( u.get_highest_category() == "INSECT" ||
1548 u.get_highest_category() == "SPIDER" ) ) ) {
1549 inhaled |= u.add_env_effect( effect_badpoison, bp_mouth, 5, intensity * 1_minutes );
1550 u.hurtall( rng( intensity, intensity * 2 ), nullptr );
1551 u.add_msg_if_player( m_bad, _( "The %s burns your skin." ), cur.name() );
1552 }
1553
1554 if( inhaled ) {
1555 u.add_msg_if_player( m_bad, _( "The %s makes you feel sick." ), cur.name() );
1556 }
1557 }
1558 }
1559 }
1560 }
1561}
std::string body_part_name_accusative(body_part bp, int number)
Returns the matching accusative name of the body_part token, i.e.
Definition: bodypart.cpp:329
@ bp_foot_l
Definition: bodypart.h:50
@ bp_leg_r
Definition: bodypart.h:49
@ bp_eyes
Definition: bodypart.h:42
@ bp_hand_l
Definition: bodypart.h:46
@ bp_arm_l
Definition: bodypart.h:44
@ bp_leg_l
Definition: bodypart.h:48
@ bp_hand_r
Definition: bodypart.h:47
@ bp_head
Definition: bodypart.h:41
@ bp_torso
Definition: bodypart.h:40
@ bp_mouth
Definition: bodypart.h:43
@ bp_foot_r
Definition: bodypart.h:51
@ bp_arm_r
Definition: bodypart.h:45
bool is_elec_immune() const override
Returns true is the player is protected from electric shocks.
Definition: character.cpp:6191
bool worn_with_flag(const std::string &flag, const bodypart_id &bp=bodypart_str_id::NULL_ID()) const
Returns true if the player is wearing an item with the given flag.
Definition: character.cpp:3270
bool is_on_ground() const override
Returns true if the player is knocked over or has broken legs.
Definition: character.cpp:962
std::list< item > worn
Definition: character.h:1507
int get_env_resist(bodypart_id bp) const override
Returns overall env_resist on a body_part.
Definition: character.cpp:7133
bool has_two_arms() const
Returns true if the player has two functioning arms.
Definition: character.cpp:1280
int get_armor_cut(bodypart_id bp) const override
Returns overall cutting resistance for the body_part.
Definition: character.cpp:6976
std::string get_highest_category() const
Returns the highest mutation category.
Definition: character.cpp:7970
bool is_wearing(const item &itm) const
Returns true if the player is wearing the item.
Definition: character.cpp:3240
void hurtall(int dam, Creature *source, bool disturb=true)
Hurts all body parts for dam, no armor reduction.
Definition: character.cpp:8666
bool has_trait(const trait_id &b) const override
Returns true if the player has the entered trait.
Definition: mutation.cpp:103
bool irradiate(float rads, bool bypass=false)
Handles mitigation and application of radiation.
Definition: suffer.cpp:1534
static body_part hp_to_bp(hp_part hpart)
Converts an hp_part to a body_part.
Definition: character.cpp:6589
bool has_active_bionic(const bionic_id &b) const
Returns true if the player has the entered bionic id and it is powered on.
Definition: character.cpp:1887
bodypart_id get_random_body_part(bool main=false) const
Definition: creature.cpp:1620
virtual bool is_underwater() const
Definition: creature.cpp:174
std::vector< bodypart_id > get_all_body_parts(bool only_main=false) const
Returns body parts this creature have.
Definition: creature.cpp:1627
int extra_radiation_min() const
Definition: field.cpp:14
int radiation_hurt_damage_min() const
Definition: field.cpp:24
std::string radiation_hurt_message() const
Definition: field.cpp:34
int extra_radiation_max() const
Definition: field.cpp:19
std::string name() const
Definition: field.h:84
int radiation_hurt_damage_max() const
Definition: field.cpp:29
int get_coverage() const
Returns the relative coverage that this item has when worn.
Definition: item.cpp:5780
bool covers(body_part bp) const
Whether this item (when worn) covers the given body part.
Definition: item.cpp:743
int burn_body_part(player &u, field_entry &cur, body_part bp, int scale)
Definition: map_field.cpp:124
void mod_pain(int npain) override
Modifies a pain value by player traits before passing it to Creature::mod_pain()
Definition: player.cpp:945
void add_msg_if_player(const std::string &msg) const override
Definition: player.cpp:3973
bool is_player() const override
Definition: player.h:106
field_type_id fd_bees
Definition: field_type.cpp:371
static const trait_id trait_M_SKIN3("M_SKIN3")
static const std::string flag_GAS_PROOF("GAS_PROOF")
static const efftype_id effect_fungus("fungus")
static const trait_id trait_ELECTRORECEPTORS("ELECTRORECEPTORS")
static const trait_id trait_THRESH_MARLOSS("THRESH_MARLOSS")
static const trait_id trait_WEB_WALKER("WEB_WALKER")
static const efftype_id effect_badpoison("badpoison")
static const itype_id itype_rm13_armor_on("rm13_armor_on")
static const trait_id trait_M_IMMUNE("M_IMMUNE")
static const trait_id trait_THRESH_MYCUS("THRESH_MYCUS")
static const trait_id trait_ACIDPROOF("ACIDPROOF")
static const trait_id trait_M_SKIN2("M_SKIN2")
static const efftype_id effect_stung("stung")
static const efftype_id effect_poison("poison")
static const efftype_id effect_teargas("teargas")
static const bionic_id bio_heatsink("bio_heatsink")
hp_part
Definition: pldata.h:32
@ num_hp_parts
Definition: pldata.h:39
int type_damage(damage_type dt) const
Definition: damage.cpp:172
#define translate_marker(x)
Marks a string literal to be extracted for translation.
Definition: translations.h:30

References _, Creature::add_effect(), Creature::add_env_effect(), add_msg(), player::add_msg_if_player(), player::add_msg_player_or_npc(), bio_heatsink, body_part_name_accusative(), bp_arm_l, bp_arm_r, bp_eyes, bp_foot_l, bp_foot_r, bp_hand_l, bp_hand_r, bp_head, bp_leg_l, bp_leg_r, bp_mouth, bp_torso, burn_body_part(), Creature::check_dead_state(), convert_bp(), item::covers(), Character::deal_damage(), DT_ELECTRIC, DT_HEAT, effect_badpoison, effect_blind, effect_fungus, effect_onfire, effect_poison, effect_stung, effect_teargas, effect_webbed, field_entry::extra_radiation_max(), field_entry::extra_radiation_min(), fd_acid, fd_acid_vent, fd_bees, fd_dazzling, fd_electricity, fd_fatigue, fd_fire, fd_flame_burst, fd_fungal_haze, fd_fungicidal_gas, fd_incendiary, fd_insecticidal_gas, fd_sap, fd_shock_vent, fd_sludge, fd_tear_gas, fd_web, flag_GAS_PROOF(), Creature::get_all_body_parts(), Character::get_armor_cut(), item::get_coverage(), Character::get_env_resist(), get_field(), field_entry::get_field_intensity(), field_entry::get_field_type(), Character::get_highest_category(), Creature::get_random_body_part(), Character::has_active_bionic(), Character::has_trait(), Character::has_two_arms(), Character::hp_to_bp(), Character::hurtall(), string_id< T >::id(), Character::in_vehicle, Character::irradiate(), Character::is_elec_immune(), field_entry::is_field_alive(), Character::is_on_ground(), player::is_player(), Creature::is_underwater(), Character::is_wearing(), itype_rm13_armor_on, m_bad, m_warning, player::mod_pain(), Creature::moves, field_entry::name(), num_bp, num_hp_parts, one_in(), Character::pos(), field_entry::radiation_hurt_damage_max(), field_entry::radiation_hurt_damage_min(), field_entry::radiation_hurt_message(), rng(), field_entry::set_field_intensity(), teleport::teleport(), dealt_damage_instance::total_damage(), trait_ACIDPROOF, trait_ELECTRORECEPTORS, trait_M_IMMUNE, trait_M_SKIN2, trait_M_SKIN3, trait_THRESH_MARLOSS, trait_THRESH_MYCUS, trait_WEB_WALKER, translate_marker, dealt_damage_instance::type_damage(), veh_at(), Character::worn, Character::worn_with_flag(), and x_in_y().

Referenced by creature_in_field().

◆ point_within_camp()

bool map::point_within_camp ( const tripoint point_check) const

Definition at line 5565 of file map.cpp.

5566{
5567 // TODO: fix point types
5568 const tripoint_abs_omt omt_check( ms_to_omt_copy( point_check ) );
5569 const point_abs_omt p = omt_check.xy();
5570 for( int x2 = -2; x2 < 2; x2++ ) {
5571 for( int y2 = -2; y2 < 2; y2++ ) {
5572 if( cata::optional<basecamp *> bcp = overmap_buffer.find_camp( p + point( x2, y2 ) ) ) {
5573 return ( *bcp )->camp_omt_pos().z() == point_check.z;
5574 }
5575 }
5576 }
5577 return false;
5578}
constexpr auto xy() const
Definition: coordinates.h:130
cata::optional< basecamp * > find_camp(const point_abs_omt &p)

References overmapbuffer::find_camp(), ms_to_omt_copy(), overmap_buffer, coords::coord_point< Point, Origin, Scale >::xy(), and tripoint::z.

Referenced by npc::worker_downtime().

◆ points_in_radius()

tripoint_range< tripoint > map::points_in_radius ( const tripoint center,
size_t  radius,
size_t  radiusz = 0 
) const

Definition at line 8617 of file map.cpp.

8619{
8620 const tripoint min( std::max<int>( 0, center.x - radius ), std::max<int>( 0, center.y - radius ),
8621 clamp<int>( center.z - radiusz, -OVERMAP_DEPTH, OVERMAP_HEIGHT ) );
8622 const tripoint max( std::min<int>( SEEX * my_MAPSIZE - 1, center.x + radius ),
8623 std::min<int>( SEEX * my_MAPSIZE - 1, center.y + radius ), clamp<int>( center.z + radiusz,
8625 return tripoint_range<tripoint>( min, max );
8626}

References center, my_MAPSIZE, OVERMAP_DEPTH, OVERMAP_HEIGHT, and SEEX.

Referenced by computer_session::action_blood_anal(), computer_session::action_conveyor(), computer_session::action_data_anal(), computer_session::action_deactivate_shock_vent(), computer_session::action_extract_rad_source(), computer_session::action_geiger(), computer_session::action_irradiator(), computer_session::action_sample(), Character::activate_bionic(), add_splash(), Character::adjacent_tile(), npc::alt_attack(), apply_ammo_effects(), are_requirements_nearby(), npc::assess_danger(), bash_furn_success(), Character::blossoms(), activity_handlers::butcher_finish(), leap_actor::call(), can_do_activity_there(), iexamine::cardreader(), iexamine::cardreader_foodplace(), deploy_tent_actor::check_intact(), choose_adjacent_highlight(), activity_handlers::chop_tree_finish(), climb_difficulty(), collapse_at(), collapse_check(), complete_construction(), consider_butchery(), game::control_vehicle(), displace_water(), enumerate_objects_around_point(), Character::env_surgery_bonus(), ranged::execute_shaped_attack(), ranged::expected_coverage(), computer_session::failure_destroy_blood(), computer_session::failure_destroy_data(), computer_session::failure_manhacks(), computer_session::failure_secubots(), computer_session::failure_shutdown(), find_empty_spot_nearby(), find_furnitures_or_vparts_with_flag_in_radius(), find_furnitures_with_flag_in_radius(), find_potential_computer_point(), hacking_activity_actor::finish(), activity_handlers::forage_finish(), game::forced_door_closing(), basecamp::form_crafting_inventory(), inventory::form_from_map(), generic_multi_activity_check_requirement(), generic_multi_activity_locations(), get_creatures_in_radius(), get_heat_radiation(), liquid_handler::get_liquid_target(), zone_manager::get_point_set_loot(), iexamine::getGasPumpByNumber(), iexamine::getNearFilledGasTank(), getNearPumpCount(), npc::go_to_omt_destination(), handle_action_menu(), has_adjacent_furniture_with(), has_nearby_chair(), has_nearby_fire(), has_nearby_table(), has_neighbor(), is_cornerfloor(), is_wall_adjacent(), map_funcs::migo_nerve_cage_removal(), game::monmove(), npc::move_away_from(), MapExtras::mx_casings(), MapExtras::mx_corpses(), MapExtras::mx_looters(), MapExtras::mx_marloss_pilgrimage(), MapExtras::mx_mayhem(), MapExtras::mx_minefield(), MapExtras::mx_portal(), MapExtras::mx_portal_in(), iexamine::nanofab(), iuse::note_bionics(), trap::on_disarmed(), operator_present(), tutorial_game::per_turn(), photo_def_for_camera_point(), place_construction(), game::place_critter_around(), mission_start::place_deposit_box(), game::place_player(), place_vending(), iexamine::portable_structure(), tutorial_game::post_action(), game::process_artifact(), process_fields_in_submap(), propagate_suspension_check(), avatar_action::ramp_move(), reachable_flood_steps(), editmap::recalc_target(), requirements_map(), mattack::riotbot(), route_adjacent(), mattack::shriek_stun(), spawn_monsters_submap(), mdeath::splatter(), Character::spores(), fungal_effects::spread_fungus(), spread_gas(), monster::stumble(), activity_handlers::travel_do_turn(), explosion_iuse::trigger_explosion(), try_remove_grab(), turnOnSelectedPump(), place_trap_actor::use(), deploy_tent_actor::use(), use_amount(), game::vertical_move(), and npc::worker_downtime().

◆ points_in_rectangle()

tripoint_range< tripoint > map::points_in_rectangle ( const tripoint from,
const tripoint to 
) const

Definition at line 8607 of file map.cpp.

8608{
8609 const tripoint min( std::max( 0, std::min( from.x, to.x ) ), std::max( 0, std::min( from.y,
8610 to.y ) ), std::max( -OVERMAP_DEPTH, std::min( from.z, to.z ) ) );
8611 const tripoint max( std::min( SEEX * my_MAPSIZE - 1, std::max( from.x, to.x ) ),
8612 std::min( SEEX * my_MAPSIZE - 1, std::max( from.y, to.y ) ), std::min( OVERMAP_HEIGHT,
8613 std::max( from.z, to.z ) ) );
8614 return tripoint_range<tripoint>( min, max );
8615}

References my_MAPSIZE, OVERMAP_DEPTH, OVERMAP_HEIGHT, SEEX, tripoint::x, tripoint::y, and tripoint::z.

Referenced by apply_camp_ownership(), apply_faction_ownership(), debug_menu::debug(), draw_lab(), farm_action(), game::find_or_make_stairs(), generate_lightmap(), jmapgen_setmap::has_vehicle_collision(), avatar_action::move(), MapExtras::mx_portal(), om_cutdown_trees(), om_harvest_furn(), om_harvest_itm(), and om_harvest_ter().

◆ points_on_zlevel() [1/2]

◆ points_on_zlevel() [2/2]

tripoint_range< tripoint > map::points_on_zlevel ( int  z) const

Same as above, but uses the specific z-level.

If the given z-level is invalid, it returns an empty range.

Definition at line 8628 of file map.cpp.

8629{
8630 if( z < -OVERMAP_DEPTH || z > OVERMAP_HEIGHT ) {
8631 // TODO: need a default constructor that creates an empty range.
8633 }
8635 tripoint( 0, 0, z ), tripoint( SEEX * my_MAPSIZE - 1, SEEY * my_MAPSIZE - 1, z ) );
8636}

References my_MAPSIZE, OVERMAP_HEIGHT, SEEX, SEEY, tripoint_above, and tripoint_zero.

◆ process_falling()

void map::process_falling ( )

Invoked drop_everything on cached dirty tiles.

Definition at line 2274 of file map.cpp.

2275{
2276 if( !zlevels ) {
2277 support_cache_dirty.clear();
2278 return;
2279 }
2280
2281 if( !support_cache_dirty.empty() ) {
2282 add_msg( m_debug, "Checking %d tiles for falling objects",
2283 support_cache_dirty.size() );
2284 // We want the cache to stay constant, but falling can change it
2285 std::set<tripoint> last_cache = std::move( support_cache_dirty );
2286 support_cache_dirty.clear();
2287 for( const tripoint &p : last_cache ) {
2288 drop_everything( p );
2289 }
2290 }
2291}
void drop_everything(const tripoint &p)
Handles map objects of given type (not creatures) falling down.
Definition: map.cpp:2045
std::set< tripoint > support_cache_dirty
Definition: map.h:1552

References add_msg(), drop_everything(), m_debug, avatar_action::move(), support_cache_dirty, and zlevels.

Referenced by game::do_turn().

◆ process_fields()

void map::process_fields ( )

Definition at line 141 of file map_field.cpp.

142{
143 const int minz = zlevels ? -OVERMAP_DEPTH : abs_sub.z;
144 const int maxz = zlevels ? OVERMAP_HEIGHT : abs_sub.z;
145 for( int z = minz; z <= maxz; z++ ) {
146 auto &field_cache = get_cache( z ).field_cache;
147 for( int x = 0; x < my_MAPSIZE; x++ ) {
148 for( int y = 0; y < my_MAPSIZE; y++ ) {
149 if( field_cache[ x + y * MAPSIZE ] ) {
150 submap *const current_submap = get_submap_at_grid( { x, y, z } );
151 process_fields_in_submap( current_submap, tripoint( x, y, z ) );
152 }
153 }
154 }
155
156 // no need to invalidate "transparency" and "seen" caches here
157 // they are invalidated point by point inside the `process_fields_in_submap`
158 }
159}
void process_fields_in_submap(submap *current_submap, const tripoint &submap_pos)
Definition: map_field.cpp:396

References abs_sub, level_cache::field_cache, get_cache(), get_submap_at_grid(), MAPSIZE, my_MAPSIZE, OVERMAP_DEPTH, OVERMAP_HEIGHT, process_fields_in_submap(), tripoint::z, and zlevels.

Referenced by game::do_turn().

◆ process_fields_in_submap()

void map::process_fields_in_submap ( submap current_submap,
const tripoint submap_pos 
)

Definition at line 396 of file map_field.cpp.

398{
399 scent_block sblk( submap, g->scent );
400
401 // Holds m.field_at(x,y).find_field(fd_some_field) type returns.
402 // Just to avoid typing that long string for a temp value.
403 field_entry *tmpfld = nullptr;
404
405 map &here = get_map();
406 tripoint thep;
407 thep.z = submap.z;
408
409 // Initialize the map tile wrapper
410 maptile map_tile( current_submap, point_zero );
411 int &locx = map_tile.pos_.x;
412 int &locy = map_tile.pos_.y;
413 const point sm_offset( submap.x * SEEX, submap.y * SEEY );
414
415 // Loop through all tiles in this submap indicated by current_submap
416 for( locx = 0; locx < SEEX; locx++ ) {
417 for( locy = 0; locy < SEEY; locy++ ) {
418 // Get a reference to the field variable from the submap;
419 // contains all the pointers to the real field effects.
420 field &curfield = current_submap->get_field( { static_cast<int>( locx ), static_cast<int>( locy ) } );
421
422 // when displayed_field_type == fd_null it means that `curfield` has no fields inside
423 // avoids instantiating (relatively) expensive map iterator
424 if( !curfield.displayed_field_type() ) {
425 continue;
426 }
427
428 // This is a translation from local coordinates to submap coordinates.
429 // All submaps are in one long 1d array.
430 thep.x = locx + sm_offset.x;
431 thep.y = locy + sm_offset.y;
432 // A const reference to the tripoint above, so that the code below doesn't accidentally change it
433 const tripoint &p = thep;
434
435 // This should be true only when the field in the current tile changes transparency state,
436 // More correctly: not just when the field is opaque, but when it changes state
437 // to a more/less transparent one
438 bool dirty_transparency_cache = false;
439
440 for( auto it = curfield.begin(); it != curfield.end(); ) {
441 // Iterating through all field effects in the submap's field.
442 field_entry &cur = it->second;
443
444 // Holds cur.get_field_type() as that is what the old system used before rewrite.
445 field_type_id cur_fd_type_id = cur.get_field_type();
446
447 // The field might have been killed by processing a neighbor field
448 if( !cur.is_field_alive() ) {
449 if( !cur_fd_type_id->get_transparent( cur.get_field_intensity() - 1 ) ) {
450 dirty_transparency_cache = true;
451 }
452 --current_submap->field_count;
453 curfield.remove_field( it++ );
454 continue;
455 }
456
457 // Again, legacy support in the event someone Mods set_field_intensity to allow more values.
458 if( cur.get_field_intensity() > 3 || cur.get_field_intensity() < 1 ) {
459 // TODO: Remove this eventually as we would suppoort more than 3 field intensity levels
460 debugmsg( "Whoooooa intensity of %d", cur.get_field_intensity() );
461 }
462
463 dirty_transparency_cache |= cur_fd_type_id->dirty_transparency_cache;
464
465 // Don't process "newborn" fields. This gives the player time to run if they need to.
466 if( cur.get_field_age() == 0_turns ) {
467 cur_fd_type_id = fd_null;
468 }
469
470 const field_type &cur_fd_type = *cur_fd_type_id;
471
472 // Upgrade field intensity
473 if( cur.intensity_upgrade_chance() > 0 &&
475 cur.intensity_upgrade_duration() > 0_turns &&
478 }
479
480 int part;
481 const ter_t &ter = map_tile.get_ter_t();
482 // Dissipate faster in water
483 if( ter.has_flag( TFLAG_SWIMMABLE ) ) {
485 }
486 if( cur_fd_type_id == fd_acid ) {
487 // Try to fall by a z-level
488 if( zlevels && p.z > -OVERMAP_DEPTH ) {
489 tripoint dst{ p.xy(), p.z - 1 };
490 if( valid_move( p, dst, true, true ) ) {
491 field_entry *acid_there = field_at( dst ).find_field( fd_acid );
492 if( acid_there == nullptr ) {
494 } else {
495 // Math can be a bit off,
496 // but "boiling" falling acid can be allowed to be stronger
497 // than acid that just lies there
498 const int sum_intensity = cur.get_field_intensity() + acid_there->get_field_intensity();
499 const int new_intensity = std::min( 3, sum_intensity );
500 // No way to get precise elapsed time, let's always reset
501 // Allow falling acid to last longer than regular acid to show it off
502 const time_duration new_age = -1_minutes * ( sum_intensity - new_intensity );
503 acid_there->set_field_intensity( new_intensity );
504 acid_there->set_field_age( new_age );
505 }
506
507 // Set ourselves up for removal
508 cur.set_field_intensity( 0 );
509 }
510 }
511 // TODO: Allow spreading to the sides if age < 0 && intensity == 3
512 }
513 if( cur_fd_type.apply_slime_factor > 0 ) {
514 sblk.apply_slime( p, cur.get_field_intensity() * cur_fd_type.apply_slime_factor );
515 }
516 if( cur_fd_type_id == fd_fire ) {
517 cur.set_field_age( std::max( -24_hours, cur.get_field_age() ) );
518 // Entire objects for ter/frn for flags
519 const ter_t &ter = map_tile.get_ter_t();
520 const furn_t &frn = map_tile.get_furn_t();
521
522 // We've got ter/furn cached, so let's use that
523 const bool is_sealed = ter_furn_has_flag( ter, frn, TFLAG_SEALED ) &&
525 // Consumed items count
526 int consumed = 0;
527 // How much time to add to the fire's life due to burned items/terrain/furniture
528 time_duration time_added = 0_turns;
529 // Checks if the fire can spread
530 const bool can_spread = !ter_furn_has_flag( ter, frn, TFLAG_FIRE_CONTAINER );
531 const bool no_floor = ter.has_flag( TFLAG_NO_FLOOR );
532 // If the flames are in furniture with fire_container flag like brazier or oven,
533 // they're fully contained, so skip consuming terrain
534 const bool can_burn = !no_floor && can_spread &&
535 ( check_flammable( ter ) || check_flammable( frn ) );
536 // The huge indent below should probably be somehow moved away from here
537 // without forcing the function to use i_at( p ) for fires without items
538 if( !is_sealed && map_tile.get_item_count() > 0 ) {
539 map_stack items_here = i_at( p );
540 std::vector<item> new_content;
541 for( auto explosive = items_here.begin(); explosive != items_here.end(); ) {
542 if( explosive->will_explode_in_fire() ) {
543 // We need to make a copy because the iterator validity is not predictable
544 item copy = *explosive;
545 explosive = items_here.erase( explosive );
546 if( copy.detonate( p, new_content ) ) {
547 // Need to restart, iterators may not be valid
548 explosive = items_here.begin();
549 }
550 } else {
551 ++explosive;
552 }
553 }
554
555 fire_data frd( cur.get_field_intensity(), !can_spread );
556 // The highest # of items this fire can remove in one turn
557 int max_consume = cur.get_field_intensity() * 2;
558
559 for( auto fuel = items_here.begin(); fuel != items_here.end() && consumed < max_consume; ) {
560 // `item::burn` modifies the charges in order to simulate some of them getting
561 // destroyed by the fire, this changes the item weight, but may not actually
562 // destroy it. We need to spawn products anyway.
563 const units::mass old_weight = fuel->weight( false );
564 bool destroyed = fuel->burn( frd );
565 // If the item is considered destroyed, it may have negative charge count,
566 // see `item::burn?. This in turn means `item::weight` returns a negative value,
567 // which we can not use, so only call `weight` when it's still an existing item.
568 const units::mass new_weight = destroyed ? 0_gram : fuel->weight( false );
569 if( old_weight != new_weight ) {
570 create_burnproducts( p, *fuel, old_weight - new_weight );
571 }
572
573 if( destroyed ) {
574 // If we decided the item was destroyed by fire, remove it.
575 // But remember its contents, except for irremovable mods, if any
576 const std::list<item *> content_list = fuel->contents.all_items_top();
577 for( item *it : content_list ) {
578 if( !it->is_irremovable() ) {
579 new_content.push_back( item( *it ) );
580 }
581 }
582 fuel = items_here.erase( fuel );
583 consumed++;
584 } else {
585 ++fuel;
586 }
587 }
588
589 spawn_items( p, new_content );
590 time_added = 1_turns * roll_remainder( frd.fuel_produced );
591 }
592
593 // Get the part of the vehicle in the fire (_internal skips the boundary check)
594 vehicle *veh = veh_at_internal( p, part );
595 if( veh != nullptr ) {
596 veh->damage( part, cur.get_field_intensity() * 10, DT_HEAT, true );
597 // Damage the vehicle in the fire.
598 }
599 if( can_burn ) {
600 if( ter.has_flag( TFLAG_SWIMMABLE ) ) {
601 // Flames die quickly on water
602 cur.set_field_age( cur.get_field_age() + 4_minutes );
603 }
604
605 // Consume the terrain we're on
606 if( ter_furn_has_flag( ter, frn, TFLAG_FLAMMABLE ) ) {
607 // The fire feeds on the ground itself until max intensity.
608 time_added += 1_turns * ( 5 - cur.get_field_intensity() );
609 if( cur.get_field_intensity() > 1 &&
610 one_in( 200 - cur.get_field_intensity() * 50 ) ) {
611 destroy( p, false );
612 }
613
614 } else if( ter_furn_has_flag( ter, frn, TFLAG_FLAMMABLE_HARD ) &&
615 one_in( 3 ) ) {
616 // The fire feeds on the ground itself until max intensity.
617 time_added += 1_turns * ( 4 - cur.get_field_intensity() );
618 if( cur.get_field_intensity() > 1 &&
619 one_in( 200 - cur.get_field_intensity() * 50 ) ) {
620 destroy( p, false );
621 }
622
623 } else if( ter.has_flag( TFLAG_FLAMMABLE_ASH ) ) {
624 // The fire feeds on the ground itself until max intensity.
625 time_added += 1_turns * ( 5 - cur.get_field_intensity() );
626 if( cur.get_field_intensity() > 1 &&
627 one_in( 200 - cur.get_field_intensity() * 50 ) ) {
628 if( p.z > 0 ) {
629 // We're in the air
630 ter_set( p, t_open_air );
631 } else {
632 ter_set( p, t_dirt );
633 }
634 }
635
636 } else if( frn.has_flag( TFLAG_FLAMMABLE_ASH ) ) {
637 // The fire feeds on the ground itself until max intensity.
638 time_added += 1_turns * ( 5 - cur.get_field_intensity() );
639 if( cur.get_field_intensity() > 1 &&
640 one_in( 200 - cur.get_field_intensity() * 50 ) ) {
641 furn_set( p, f_ash );
642 add_item_or_charges( p, item( "ash" ) );
643 }
644
645 }
646 }
647
648 if( ter.has_flag( TFLAG_NO_FLOOR ) && zlevels && p.z > -OVERMAP_DEPTH ) {
649 // We're hanging in the air - let's fall down
650 tripoint dst{ p.xy(), p.z - 1 };
651 if( valid_move( p, dst, true, true ) ) {
652 maptile dst_tile = maptile_at_internal( dst );
653 field_entry *fire_there = dst_tile.find_field( fd_fire );
654 if( fire_there == nullptr ) {
655 add_field( dst, fd_fire, 1, 0_turns, false );
657 } else {
658 // Don't fuel raging fires or they'll burn forever
659 // as they can produce small fires above themselves
660 int new_intensity = std::max( cur.get_field_intensity(),
661 fire_there->get_field_intensity() );
662 // Allow smaller fires to combine
663 if( new_intensity < 3 &&
664 cur.get_field_intensity() == fire_there->get_field_intensity() ) {
665 new_intensity++;
666 }
667 // A raging fire below us can support us for a while
668 // Otherwise decay and decay fast
669 if( fire_there->get_field_intensity() < 3 || one_in( 10 ) ) {
671 }
672 fire_there->set_field_intensity( new_intensity );
673 }
674 break;
675 }
676 }
677 // Lower age is a longer lasting fire
678 if( time_added != 0_turns ) {
679 cur.set_field_age( cur.get_field_age() - time_added );
680 } else if( can_burn ) {
681 // Nothing to burn = fire should be dying out faster
682 // Drain more power from big fires, so that they stop raging over nothing
683 // Except for fires on stoves and fireplaces, those are made to keep the fire alive
684 cur.mod_field_age( 10_seconds * cur.get_field_intensity() );
685 }
686
687 // Allow raging fires (and only raging fires) to spread up
688 // Spreading down is achieved by wrecking the walls/floor and then falling
689 if( zlevels && cur.get_field_intensity() == 3 && p.z < OVERMAP_HEIGHT ) {
690 const tripoint dst_p = tripoint( p.xy(), p.z + 1 );
691 // Let it burn through the floor
692 maptile dst = maptile_at_internal( dst_p );
693 const auto &dst_ter = dst.get_ter_t();
694 if( dst_ter.has_flag( TFLAG_NO_FLOOR ) ||
695 dst_ter.has_flag( TFLAG_FLAMMABLE ) ||
696 dst_ter.has_flag( TFLAG_FLAMMABLE_ASH ) ||
697 dst_ter.has_flag( TFLAG_FLAMMABLE_HARD ) ) {
698 field_entry *nearfire = dst.find_field( fd_fire );
699 if( nearfire != nullptr ) {
700 nearfire->mod_field_age( -2_turns );
701 } else {
702 add_field( dst_p, fd_fire, 1, 0_turns, false );
703 }
704 // Fueling fires above doesn't cost fuel
705 }
706 }
707
708 // Below we will access our nearest 8 neighbors, so let's cache them now
709 // This should probably be done more globally, because large fires will re-do it a lot
710 auto neighs = get_neighbors( p );
711
712 // If the flames are in a pit, it can't spread to non-pit
713 const bool in_pit = can_spread && ter.id.id() == t_pit;
714
715 // Count adjacent fires, to optimize out needless smoke and hot air
716 int adjacent_fires = 0;
717
718 // If the flames are big, they contribute to adjacent flames
719 if( can_spread ) {
720 if( cur.get_field_intensity() > 1 && one_in( 3 ) ) {
721 // Basically: Scan around for a spot,
722 // if there is more fire there, make it bigger and give it some fuel.
723 // This is how big fires spend their excess age:
724 // making other fires bigger. Flashpoint.
725 size_t end_it = static_cast<size_t>( rng( 0, neighs.size() - 1 ) );
726 for( size_t i = ( end_it + 1 ) % neighs.size(), count = 0;
727 count != neighs.size() && cur.get_field_age() < 0_turns;
728 i = ( i + 1 ) % neighs.size(), count++ ) {
729 maptile &dst = neighs[i].second;
730 auto dstfld = dst.find_field( fd_fire );
731 // If the fire exists and is weaker than ours, boost it
732 if( dstfld != nullptr &&
733 ( dstfld->get_field_intensity() <= cur.get_field_intensity() ||
734 dstfld->get_field_age() > cur.get_field_age() ) &&
735 ( in_pit == ( dst.get_ter() == t_pit ) ) ) {
736 if( dstfld->get_field_intensity() < 2 ) {
737 dstfld->set_field_intensity( dstfld->get_field_intensity() + 1 );
738 }
739
740 dstfld->set_field_age( dstfld->get_field_age() - 5_minutes );
741 cur.set_field_age( cur.get_field_age() + 5_minutes );
742 }
743 if( dstfld != nullptr ) {
744 adjacent_fires++;
745 }
746 }
747 } else if( cur.get_field_age() < 0_turns && cur.get_field_intensity() < 3 ) {
748 // See if we can grow into a stage 2/3 fire, for this
749 // burning neighbors are necessary in addition to
750 // field age < 0, or alternatively, a LOT of fuel.
751
752 // The maximum fire intensity is 1 for a lone fire, 2 for at least 1 neighbor,
753 // 3 for at least 2 neighbors.
754 int maximum_intensity = 1;
755
756 // The following logic looks a bit complex due to optimization concerns, so here are the semantics:
757 // 1. Calculate maximum field intensity based on fuel, -50 minutes is 2(medium), -500 minutes is 3(raging)
758 // 2. Calculate maximum field intensity based on neighbors, 3 neighbors is 2(medium), 7 or more neighbors is 3(raging)
759 // 3. Pick the higher maximum between 1. and 2.
760 if( cur.get_field_age() < -500_minutes ) {
761 maximum_intensity = 3;
762 } else {
763 for( auto &neigh : neighs ) {
764 if( neigh.second.get_field().find_field( fd_fire ) != nullptr ) {
765 adjacent_fires++;
766 }
767 }
768 maximum_intensity = 1 + ( adjacent_fires >= 3 ) + ( adjacent_fires >= 7 );
769
770 if( maximum_intensity < 2 && cur.get_field_age() < -50_minutes ) {
771 maximum_intensity = 2;
772 }
773 }
774
775 // If we consumed a lot, the flames grow higher
776 if( cur.get_field_intensity() < maximum_intensity && cur.get_field_age() < 0_turns ) {
777 // Fires under 0 age grow in size. Level 3 fires under 0 spread later on.
778 // Weaken the newly-grown fire
780 cur.set_field_age( cur.get_field_age() + 10_minutes * cur.get_field_intensity() );
781 }
782 }
783
784 // Consume adjacent fuel / terrain / webs to spread.
785 // Our iterator will start at end_i + 1 and increment from there and then wrap around.
786 // This guarantees it will check all neighbors, starting from a random one
787 const size_t end_i = static_cast<size_t>( rng( 0, neighs.size() - 1 ) );
788 for( size_t i = ( end_i + 1 ) % neighs.size(), count = 0;
789 count != neighs.size();
790 i = ( i + 1 ) % neighs.size(), count++ ) {
791 if( one_in( cur.get_field_intensity() * 2 ) ) {
792 // Skip some processing to save on CPU
793 continue;
794 }
795
796 tripoint &dst_p = neighs[i].first;
797 maptile &dst = neighs[i].second;
798 // No bounds checking here: we'll treat the invalid neighbors as valid.
799 // We're using the map tile wrapper, so we can treat invalid tiles as sentinels.
800 // This will create small oddities on map edges, but nothing more noticeable than
801 // "cut-off" that happens with bounds checks.
802
803 field_entry *nearfire = dst.find_field( fd_fire );
804 if( nearfire != nullptr ) {
805 // We handled supporting fires in the section above, no need to do it here
806 continue;
807 }
808
809 field_entry *nearwebfld = dst.find_field( fd_web );
810 int spread_chance = 25 * ( cur.get_field_intensity() - 1 );
811 if( nearwebfld != nullptr ) {
812 spread_chance = 50 + spread_chance / 2;
813 }
814
815 const ter_t &dster = dst.get_ter_t();
816 const furn_t &dsfrn = dst.get_furn_t();
817 // Allow weaker fires to spread occasionally
818 const int power = cur.get_field_intensity() + one_in( 5 );
819 if( can_spread && rng( 1, 100 ) < spread_chance &&
820 ( check_flammable( dster ) || check_flammable( dsfrn ) ) &&
821 ( in_pit == ( dster.id.id() == t_pit ) ) &&
822 (
823 ( power >= 3 && cur.get_field_age() < 0_turns && one_in( 20 ) ) ||
824 ( power >= 2 && ( ter_furn_has_flag( dster, dsfrn, TFLAG_FLAMMABLE ) && one_in( 2 ) ) ) ||
825 ( power >= 2 && ( ter_furn_has_flag( dster, dsfrn, TFLAG_FLAMMABLE_ASH ) && one_in( 2 ) ) ) ||
826 ( power >= 3 && ( ter_furn_has_flag( dster, dsfrn, TFLAG_FLAMMABLE_HARD ) && one_in( 5 ) ) ) ||
827 nearwebfld || ( dst.get_item_count() > 0 &&
829 one_in( 5 ) )
830 ) ) {
831 // Nearby open flammable ground? Set it on fire.
832 add_field( dst_p, fd_fire, 1, 0_turns, false );
833 tmpfld = dst.find_field( fd_fire );
834 if( tmpfld != nullptr ) {
835 // Make the new fire quite weak, so that it doesn't start jumping around instantly
836 tmpfld->set_field_age( 2_minutes );
837 // Consume a bit of our fuel
838 cur.set_field_age( cur.get_field_age() + 1_minutes );
839 }
840 if( nearwebfld ) {
841 nearwebfld->set_field_intensity( 0 );
842 }
843 }
844 }
845 }
846 }
847
848 // Spread gaseous fields
849 if( cur.gas_can_spread() ) {
850 const int gas_percent_spread = cur_fd_type.percent_spread;
851 if( gas_percent_spread > 0 ) {
852 const time_duration outdoor_age_speedup = cur_fd_type.outdoor_age_speedup;
853 spread_gas( cur, p, gas_percent_spread, outdoor_age_speedup, sblk );
854 }
855 }
856
857 if( cur_fd_type_id == fd_fungal_haze ) {
858 if( one_in( 10 - 2 * cur.get_field_intensity() ) ) {
859 // Haze'd terrain
860 fungal_effects( *g, here ).spread_fungus( p );
861 }
862 }
863
864 // Process npc complaints
865 const std::tuple<int, std::string, time_duration, std::string> &npc_complain_data =
866 cur_fd_type.npc_complain_data;
867 const int chance = std::get<0>( npc_complain_data );
868 if( chance > 0 && one_in( chance ) ) {
869 if( npc *const np = g->critter_at<npc>( p, false ) ) {
870 np->complain_about( std::get<1>( npc_complain_data ),
871 std::get<2>( npc_complain_data ),
872 std::get<3>( npc_complain_data ) );
873 }
874 }
875
876 // Apply radiation
877 if( cur.extra_radiation_max() > 0 ) {
878 int extra_radiation = rng( cur.extra_radiation_min(), cur.extra_radiation_max() );
879 adjust_radiation( p, extra_radiation );
880 }
881
882 // Apply wandering fields from vents
883 if( cur_fd_type.wandering_field ) {
884 for( const tripoint &pnt : points_in_radius( p, cur.get_field_intensity() - 1 ) ) {
885 field &wandering_field = get_field( pnt );
886 tmpfld = wandering_field.find_field( cur_fd_type.wandering_field );
887 if( tmpfld && tmpfld->get_field_intensity() < cur.get_field_intensity() ) {
888 tmpfld->set_field_intensity( tmpfld->get_field_intensity() + 1 );
889 } else {
890 add_field( pnt, cur_fd_type.wandering_field, cur.get_field_intensity() );
891 }
892 }
893 }
894
895 if( cur_fd_type_id == fd_fire_vent ) {
896
897 if( cur.get_field_intensity() > 1 ) {
898 if( one_in( 3 ) ) {
900 }
902 } else {
903 dirty_transparency_cache = true;
904 add_field( p, fd_flame_burst, 3, cur.get_field_age() );
905 cur.set_field_intensity( 0 );
906 }
907 }
908 if( cur_fd_type_id == fd_flame_burst ) {
909 if( cur.get_field_intensity() > 1 ) {
912 } else {
913 dirty_transparency_cache = true;
914 add_field( p, fd_fire_vent, 3, cur.get_field_age() );
915 cur.set_field_intensity( 0 );
916 }
917 }
918 if( cur_fd_type_id == fd_electricity ) {
919 // 4 in 5 chance to spread
920 if( !one_in( 5 ) ) {
921 std::vector<tripoint> valid;
922 // We're grounded
923 if( impassable( p ) && cur.get_field_intensity() > 1 ) {
924 int tries = 0;
925 tripoint pnt;
926 pnt.z = p.z;
927 while( tries < 10 && cur.get_field_age() < 5_minutes && cur.get_field_intensity() > 1 ) {
928 pnt.x = p.x + rng( -1, 1 );
929 pnt.y = p.y + rng( -1, 1 );
930 if( passable( pnt ) && !obstructed_by_vehicle_rotation( p, pnt ) ) {
931 add_field( pnt, fd_electricity, 1, cur.get_field_age() + 1_turns );
933 tries = 0;
934 } else {
935 tries++;
936 }
937 }
938 // We're not grounded; attempt to ground
939 } else {
940 for( const tripoint &dst : points_in_radius( p, 1 ) ) {
941 // Grounded tiles first
942 if( impassable( dst ) ) {
943 valid.push_back( dst );
944 }
945 }
946 // Spread to adjacent space, then
947 if( valid.empty() ) {
948 tripoint dst( p + point( rng( -1, 1 ), rng( -1, 1 ) ) );
949 field_entry *elec = get_field( dst ).find_field( fd_electricity );
950 bool pass = passable( dst ) && !obstructed_by_vehicle_rotation( p, dst );
951 if( pass && elec != nullptr &&
952 elec->get_field_intensity() < 3 ) {
953 elec->set_field_intensity( elec->get_field_intensity() + 1 );
955 } else if( pass ) {
956 add_field( dst, fd_electricity, 1, cur.get_field_age() + 1_turns );
957 }
959 }
960 while( !valid.empty() && cur.get_field_intensity() > 1 ) {
961 const tripoint target = random_entry_removed( valid );
962 add_field( target, fd_electricity, 1, cur.get_field_age() + 1_turns );
964 }
965 }
966 }
967 }
968
969 int monster_spawn_chance = cur.monster_spawn_chance();
970 int monster_spawn_count = cur.monster_spawn_count();
971 if( monster_spawn_count > 0 && monster_spawn_chance > 0 && one_in( monster_spawn_chance ) ) {
972 for( ; monster_spawn_count > 0; monster_spawn_count-- ) {
974 cur.monster_spawn_group(), &monster_spawn_count );
975 if( !spawn_details.name ) {
976 continue;
977 }
980 [this]( const tripoint & n ) {
981 return passable( n );
982 } ) ) {
983 add_spawn( spawn_details.name, spawn_details.pack_size, *spawn_point );
984 }
985 }
986 }
987
988 if( cur_fd_type_id == fd_push_items ) {
989 map_stack items = i_at( p );
990 for( auto pushee = items.begin(); pushee != items.end(); ) {
991 if( pushee->typeId() != itype_rock ||
992 pushee->age() < 1_turns ) {
993 pushee++;
994 } else {
995 item tmp = *pushee;
996 tmp.set_age( 0_turns );
997 pushee = items.erase( pushee );
998 std::vector<tripoint> valid;
999 for( const tripoint &dst : points_in_radius( p, 1 ) ) {
1000 if( get_field( dst, fd_push_items ) != nullptr ) {
1001 valid.push_back( dst );
1002 }
1003 }
1004 if( !valid.empty() ) {
1005 tripoint newp = random_entry( valid );
1006 add_item_or_charges( newp, tmp );
1007 if( g->u.pos() == newp ) {
1008 add_msg( m_bad, _( "A %s hits you!" ), tmp.tname() );
1009 const bodypart_id hit = g->u.get_random_body_part();
1010 g->u.deal_damage( nullptr, hit, damage_instance( DT_BASH, 6 ) );
1011 g->u.check_dead_state();
1012 }
1013
1014 if( npc *const p = g->critter_at<npc>( newp ) ) {
1015 // TODO: combine with player character code above
1016 const bodypart_id hit = g->u.get_random_body_part();
1017 p->deal_damage( nullptr, hit, damage_instance( DT_BASH, 6 ) );
1018 if( g->u.sees( newp ) ) {
1019 add_msg( _( "A %1$s hits %2$s!" ), tmp.tname(), p->name );
1020 }
1021 p->check_dead_state();
1022 } else if( monster *const mon = g->critter_at<monster>( newp ) ) {
1023 mon->apply_damage( nullptr, bodypart_id( "torso" ),
1024 6 - mon->get_armor_bash( bodypart_id( "torso" ) ) );
1025 if( g->u.sees( newp ) ) {
1026 add_msg( _( "A %1$s hits the %2$s!" ), tmp.tname(), mon->name() );
1027 }
1028 mon->check_dead_state();
1029 }
1030 }
1031 }
1032 }
1033 }
1034 if( cur_fd_type_id == fd_shock_vent ) {
1035 if( cur.get_field_intensity() > 1 ) {
1036 if( one_in( 5 ) ) {
1038 }
1039 } else {
1040 cur.set_field_intensity( 3 );
1041 int num_bolts = rng( 3, 6 );
1042 for( int i = 0; i < num_bolts; i++ ) {
1043 int xdir = 0;
1044 int ydir = 0;
1045 while( xdir == 0 && ydir == 0 ) {
1046 xdir = rng( -1, 1 );
1047 ydir = rng( -1, 1 );
1048 }
1049 int dist = rng( 4, 12 );
1050 int boltx = p.x;
1051 int bolty = p.y;
1052 for( int n = 0; n < dist; n++ ) {
1053 boltx += xdir;
1054 bolty += ydir;
1055 add_field( tripoint( boltx, bolty, p.z ), fd_electricity, rng( 2, 3 ) );
1056 if( one_in( 4 ) ) {
1057 if( xdir == 0 ) {
1058 xdir = rng( 0, 1 ) * 2 - 1;
1059 } else {
1060 xdir = 0;
1061 }
1062 }
1063 if( one_in( 4 ) ) {
1064 if( ydir == 0 ) {
1065 ydir = rng( 0, 1 ) * 2 - 1;
1066 } else {
1067 ydir = 0;
1068 }
1069 }
1070 }
1071 }
1072 }
1073 }
1074 if( cur_fd_type_id == fd_acid_vent ) {
1075
1076 if( cur.get_field_intensity() > 1 ) {
1077 if( cur.get_field_age() >= 1_minutes ) {
1079 cur.set_field_age( 0_turns );
1080 }
1081 } else {
1082 cur.set_field_intensity( 3 );
1083 for( const tripoint &t : points_in_radius( p, 5 ) ) {
1084 const field_entry *acid = get_field( t, fd_acid );
1085 if( acid != nullptr && acid->get_field_intensity() == 0 ) {
1086 int new_intensity = 3 - rl_dist( p, t ) / 2 + ( one_in( 3 ) ? 1 : 0 );
1087 if( new_intensity > 3 ) {
1088 new_intensity = 3;
1089 }
1090 if( new_intensity > 0 ) {
1091 add_field( t, fd_acid, new_intensity );
1092 }
1093 }
1094 }
1095 }
1096 }
1097 if( cur_fd_type_id == fd_bees ) {
1098 // Poor bees are vulnerable to so many other fields.
1099 // TODO: maybe adjust effects based on different fields.
1100 if( curfield.find_field( fd_web ) ||
1101 curfield.find_field( fd_fire ) ||
1102 curfield.find_field( fd_smoke ) ||
1103 curfield.find_field( fd_toxic_gas ) ||
1104 curfield.find_field( fd_tear_gas ) ||
1105 curfield.find_field( fd_relax_gas ) ||
1106 curfield.find_field( fd_nuke_gas ) ||
1107 curfield.find_field( fd_gas_vent ) ||
1108 curfield.find_field( fd_smoke_vent ) ||
1109 curfield.find_field( fd_fungicidal_gas ) ||
1110 curfield.find_field( fd_insecticidal_gas ) ||
1111 curfield.find_field( fd_fire_vent ) ||
1112 curfield.find_field( fd_flame_burst ) ||
1113 curfield.find_field( fd_electricity ) ||
1114 curfield.find_field( fd_fatigue ) ||
1115 curfield.find_field( fd_shock_vent ) ||
1116 curfield.find_field( fd_plasma ) ||
1117 curfield.find_field( fd_laser ) ||
1118 curfield.find_field( fd_dazzling ) ||
1119 curfield.find_field( fd_electricity ) ||
1120 curfield.find_field( fd_incendiary ) ) {
1121 // Kill them at the end of processing.
1122 cur.set_field_intensity( 0 );
1123 } else {
1124 // Bees chase the player if in range, wander randomly otherwise.
1125 if( !g->u.is_underwater() &&
1126 rl_dist( p, g->u.pos() ) < 10 &&
1127 clear_path( p, g->u.pos(), 10, 1, 100 ) ) {
1128
1129 std::vector<point> candidate_positions =
1130 squares_in_direction( p.xy(), point( g->u.posx(), g->u.posy() ) );
1131 for( const point &candidate_position : candidate_positions ) {
1132 field &target_field = get_field( tripoint( candidate_position, p.z ) );
1133 // Only shift if there are no bees already there.
1134 // TODO: Figure out a way to merge bee fields without allowing
1135 // Them to effectively move several times in a turn depending
1136 // on iteration direction.
1137 if( !target_field.find_field( fd_bees ) ) {
1138 add_field( tripoint( candidate_position, p.z ), fd_bees,
1139 cur.get_field_intensity(), cur.get_field_age() );
1140 cur.set_field_intensity( 0 );
1141 break;
1142 }
1143 }
1144 } else {
1145 spread_gas( cur, p, 5, 0_turns, sblk );
1146 }
1147 }
1148 }
1149 if( cur_fd_type_id == fd_incendiary ) {
1150 // Needed for variable scope
1151 tripoint dst( p + point( rng( -1, 1 ), rng( -1, 1 ) ) );
1152 if( has_flag( TFLAG_FLAMMABLE, dst ) ||
1153 has_flag( TFLAG_FLAMMABLE_ASH, dst ) ||
1154 has_flag( TFLAG_FLAMMABLE_HARD, dst ) ) {
1155 add_field( dst, fd_fire, 1 );
1156 }
1157
1158 // Check piles for flammable items and set those on fire
1159 if( flammable_items_at( dst ) ) {
1160 add_field( dst, fd_fire, 1 );
1161 }
1162
1164 }
1165 if( cur_fd_type_id == fd_fungicidal_gas ) {
1166 // Check the terrain and replace it accordingly to simulate the fungus dieing off
1167 const ter_t &ter = map_tile.get_ter_t();
1168 const furn_t &frn = map_tile.get_furn_t();
1169 const int intensity = cur.get_field_intensity();
1170 if( ter.has_flag( flag_FUNGUS ) && one_in( 10 / intensity ) ) {
1171 ter_set( p, t_dirt );
1172 }
1173 if( frn.has_flag( flag_FUNGUS ) && one_in( 10 / intensity ) ) {
1174 furn_set( p, f_null );
1175 }
1176 }
1177
1178 cur.set_field_age( cur.get_field_age() + 1_turns );
1179 auto &fdata = cur.get_field_type().obj();
1180 if( fdata.half_life > 0_turns && cur.get_field_age() > 0_turns &&
1181 dice( 2, to_turns<int>( cur.get_field_age() ) ) > to_turns<int>( fdata.half_life ) ) {
1182 cur.set_field_age( 0_turns );
1184 }
1185 if( !cur.is_field_alive() ) {
1186 --current_submap->field_count;
1187 curfield.remove_field( it++ );
1188 } else {
1189 ++it;
1190 }
1191 }
1192
1193 if( dirty_transparency_cache ) {
1195 set_seen_cache_dirty( thep );
1196 }
1197 }
1198 }
1199 const int minz = zlevels ? -OVERMAP_DEPTH : abs_sub.z;
1200 const int maxz = zlevels ? OVERMAP_HEIGHT : abs_sub.z;
1201 for( int z = std::max( submap.z - 1, minz ); z <= std::min( submap.z + 1, maxz ); ++z ) {
1202 auto &field_cache = get_cache( z ).field_cache;
1203 for( int y = std::max( submap.y - 1, 0 ); y <= std::min( submap.y + 1, MAPSIZE - 1 ); ++y ) {
1204 for( int x = std::max( submap.x - 1, 0 ); x <= std::min( submap.x + 1, MAPSIZE - 1 ); ++x ) {
1205 if( get_submap_at_grid( { x, y, z } )->field_count > 0 ) {
1206 field_cache.set( x + y * MAPSIZE );
1207 } else {
1208 field_cache.reset( x + y * MAPSIZE );
1209 }
1210 }
1211 }
1212 }
1213 sblk.commit_modifications();
1214}
bool gas_can_spread()
Definition: field.h:93
time_duration intensity_upgrade_duration() const
Definition: field.cpp:44
mongroup_id monster_spawn_group() const
Definition: field.cpp:64
time_duration get_underwater_age_speedup() const
Definition: field.h:97
int monster_spawn_count() const
Definition: field.cpp:54
time_duration mod_field_age(const time_duration &mod_age)
Adds given value to age.
Definition: field.h:73
int intensity_upgrade_chance() const
Definition: field.cpp:39
int monster_spawn_radius() const
Definition: field.cpp:59
int monster_spawn_chance() const
Definition: field.cpp:49
std::map< field_type_id, field_entry >::iterator begin()
Definition: field.cpp:251
std::map< field_type_id, field_entry >::iterator end()
Definition: field.cpp:261
void spread_fungus(const tripoint &p)
std::string tname(unsigned int quantity=1, bool with_prefix=true, unsigned int truncate=0) const
Return the (translated) item name.
Definition: item.cpp:4473
void set_age(const time_duration &age)
Definition: item.cpp:9877
bool detonate(const tripoint &p, std::vector< item > &drops)
Detonates the item and adds remains (if any) to drops.
Definition: item.cpp:8623
std::array< std::pair< tripoint, maptile >, 8 > get_neighbors(const tripoint &p)
Definition: map_field.cpp:190
void create_hot_air(const tripoint &p, int intensity)
Definition: map_field.cpp:363
bool clear_path(const tripoint &f, const tripoint &t, int range, int cost_min, int cost_max) const
Check whether there's a direct line of sight between F and T with the additional movecost restraints.
Definition: map.cpp:6407
void spread_gas(field_entry &cur, const tripoint &p, int percent_spread, const time_duration &outdoor_age_speedup, scent_block &sblk)
Definition: map_field.cpp:251
void create_burnproducts(const tripoint &p, const item &fuel, const units::mass &burned_mass)
Definition: map_field.cpp:96
field_type_id fd_laser
Definition: field_type.cpp:359
field_type_id fd_plasma
Definition: field_type.cpp:358
field_type_id fd_null
Definition: field_type.cpp:335
std::vector< point > squares_in_direction(const point &p1, const point &p2)
Definition: line.cpp:588
static const itype_id itype_rock("rock")
static bool check_flammable(const map_data_common_t &t)
Definition: map_field.cpp:354
static const std::string flag_FUNGUS("FUNGUS")
furn_id f_ash
Definition: mapdata.cpp:1097
ter_id t_pit
Definition: mapdata.cpp:625
@ TFLAG_FLAMMABLE_HARD
Definition: mapdata.h:294
@ TFLAG_FLAMMABLE
Definition: mapdata.h:277
@ TFLAG_FLAMMABLE_ASH
Definition: mapdata.h:289
@ TFLAG_FIRE_CONTAINER
Definition: mapdata.h:293
bool acid(monster *z)
Definition: monattack.cpp:585
bool get_transparent(int level=0) const
Definition: field_type.h:204
int percent_spread
Definition: field_type.h:157
field_type_id wandering_field
Definition: field_type.h:182
std::tuple< int, std::string, time_duration, std::string > npc_complain_data
Definition: field_type.h:170
time_duration outdoor_age_speedup
Definition: field_type.h:155
int apply_slime_factor
Definition: field_type.h:158
Contains the state of a fire in one tile on one turn.
Definition: fire.h:18
size_t get_item_count() const
Definition: submap.h:333
ter_id get_ter() const
Definition: submap.h:289

References _, abs_sub, mattack::acid(), add_field(), add_item_or_charges(), add_msg(), add_spawn(), adjust_radiation(), scent_block::apply_slime(), field_type::apply_slime_factor, field::begin(), item_stack::begin(), check_flammable(), clear_path(), scent_block::commit_modifications(), detail::count(), create_burnproducts(), create_hot_air(), vehicle::damage(), debugmsg, destroy(), destroyed, item::detonate(), dice(), field_type::dirty_transparency_cache, field::displayed_field_type(), DT_BASH, DT_HEAT, eight_horizontal_neighbors, field::end(), item_stack::end(), map_stack::erase(), explosive, field_entry::extra_radiation_max(), field_entry::extra_radiation_min(), f_ash, f_null, fd_acid, fd_acid_vent, fd_bees, fd_dazzling, fd_electricity, fd_fatigue, fd_fire, fd_fire_vent, fd_flame_burst, fd_fungal_haze, fd_fungicidal_gas, fd_gas_vent, fd_incendiary, fd_insecticidal_gas, fd_laser, fd_nuke_gas, fd_null, fd_plasma, fd_push_items, fd_relax_gas, fd_shock_vent, fd_smoke, fd_smoke_vent, fd_tear_gas, fd_toxic_gas, fd_web, field_at(), level_cache::field_cache, submap::field_count, maptile::find_field(), field::find_field(), flag_FUNGUS(), flammable_items_at(), fire_data::fuel_produced, furn_set(), g, field_entry::gas_can_spread(), get_cache(), submap::get_field(), get_field(), field_entry::get_field_age(), field_entry::get_field_intensity(), field_entry::get_field_type(), maptile::get_furn_t(), maptile::get_item_count(), get_map(), get_neighbors(), get_submap_at_grid(), maptile::get_ter(), maptile::get_ter_t(), field_type::get_transparent(), field_entry::get_underwater_age_speedup(), MonsterGroupManager::GetResultFromGroup(), map_data_common_t::has_flag(), has_flag(), i_at(), int_id< T >::id(), ter_t::id, string_id< T >::id(), impassable(), field_entry::intensity_upgrade_chance(), field_entry::intensity_upgrade_duration(), field_entry::is_field_alive(), itype_rock, m_bad, MAPSIZE, maptile_at_internal(), field_entry::mod_field_age(), field_entry::monster_spawn_chance(), field_entry::monster_spawn_count(), field_entry::monster_spawn_group(), field_entry::monster_spawn_radius(), MonsterGroupResult::name, field_type::npc_complain_data, int_id< T >::obj(), obstructed_by_vehicle_rotation(), calendar::once_every(), one_in(), field_type::outdoor_age_speedup, OVERMAP_DEPTH, OVERMAP_HEIGHT, MonsterGroupResult::pack_size, passable(), field_type::percent_spread, point_zero, points_in_radius(), maptile::pos_, random_entry(), random_entry_removed(), random_point(), field::remove_field(), rl_dist(), rng(), roll_remainder(), SEEX, SEEY, item::set_age(), field_entry::set_field_age(), field_entry::set_field_intensity(), set_seen_cache_dirty(), set_transparency_cache_dirty(), spawn_items(), fungal_effects::spread_fungus(), spread_gas(), squares_in_direction(), t_dirt, t_open_air, t_pit, ter(), ter_furn_has_flag(), ter_set(), TFLAG_ALLOW_FIELD_EFFECT, TFLAG_FIRE_CONTAINER, TFLAG_FLAMMABLE, TFLAG_FLAMMABLE_ASH, TFLAG_FLAMMABLE_HARD, TFLAG_NO_FLOOR, TFLAG_SEALED, TFLAG_SWIMMABLE, item::tname(), valid_move(), veh_at_internal(), field_type::wandering_field, point::x, tripoint::x, tripoint::xy(), point::y, tripoint::y, tripoint::z, and zlevels.

Referenced by process_fields().

◆ process_items()

void map::process_items ( )

Definition at line 4580 of file map.cpp.

4581{
4582 const int minz = zlevels ? -OVERMAP_DEPTH : abs_sub.z;
4583 const int maxz = zlevels ? OVERMAP_HEIGHT : abs_sub.z;
4584 for( int gz = minz; gz <= maxz; ++gz ) {
4585 level_cache &cache = access_cache( gz );
4586 std::set<tripoint> submaps_with_vehicles;
4587 for( vehicle *this_vehicle : cache.vehicle_list ) {
4588 tripoint pos = this_vehicle->global_pos3();
4589 submaps_with_vehicles.emplace( pos.x / SEEX, pos.y / SEEY, pos.z );
4590 }
4591 for( const tripoint &pos : submaps_with_vehicles ) {
4592 submap *const current_submap = get_submap_at_grid( pos );
4593 // Vehicles first in case they get blown up and drop active items on the map.
4594 process_items_in_vehicles( *current_submap );
4595 }
4596 }
4597 // Making a copy, in case the original variable gets modified during `process_items_in_submap`
4598 const std::set<tripoint> submaps_with_active_items_copy = submaps_with_active_items;
4599 for( const tripoint &abs_pos : submaps_with_active_items_copy ) {
4600 const tripoint local_pos = abs_pos - abs_sub.xy();
4601 submap *const current_submap = get_submap_at_grid( local_pos );
4602 if( !current_submap->active_items.empty() ) {
4603 process_items_in_submap( *current_submap, local_pos );
4604 }
4605 }
4606}
void process_items_in_vehicles(submap &current_submap)
Definition: map.cpp:4638
void process_items_in_submap(submap &current_submap, const tripoint &gridp)
Definition: map.cpp:4608

References abs_sub, access_cache(), submap::active_items, active_item_cache::empty(), get_submap_at_grid(), vehicle::global_pos3(), OVERMAP_DEPTH, OVERMAP_HEIGHT, wrapped_vehicle::pos, process_items_in_submap(), process_items_in_vehicles(), SEEX, SEEY, submaps_with_active_items, level_cache::vehicle_list, tripoint::x, tripoint::xy(), tripoint::y, tripoint::z, and zlevels.

Referenced by game::do_turn().

◆ process_items_in_submap()

void map::process_items_in_submap ( submap current_submap,
const tripoint gridp 
)
private

Definition at line 4608 of file map.cpp.

4609{
4610 // Get a COPY of the active item list for this submap.
4611 // If more are added as a side effect of processing, they are ignored this turn.
4612 // If they are destroyed before processing, they don't get processed.
4613 std::vector<item_reference> active_items = current_submap.active_items.get_for_processing();
4614 const point grid_offset( gridp.x * SEEX, gridp.y * SEEY );
4615 for( item_reference &active_item_ref : active_items ) {
4616 if( !active_item_ref.item_ref ) {
4617 // The item was destroyed, so skip it.
4618 continue;
4619 }
4620
4621 const tripoint map_location = tripoint( grid_offset + active_item_ref.location, gridp.z );
4622 // root cellars are special
4624 if( ter( map_location ) == t_rootcellar ) {
4626 }
4627 if( furn( map_location ) == f_fridge_on ) {
4629 }
4630 if( furn( map_location ) == f_minifreezer_on ) {
4632 }
4633 map_stack items = i_at( map_location );
4634 process_map_items( items, active_item_ref.item_ref, map_location, 1, flag );
4635 }
4636}
std::vector< item_reference > get_for_processing()
Returns the first size() / processing_speed() elements of each list, rounded up.
temperature_flag
Definition: enums.h:42
@ TEMP_NORMAL
Definition: enums.h:43
@ TEMP_FRIDGE
Definition: enums.h:45
@ TEMP_FREEZER
Definition: enums.h:46
@ TEMP_ROOT_CELLAR
Definition: enums.h:47
static bool process_map_items(item_stack &items, safe_reference< item > &item_ref, const tripoint &location, const float insulation, const temperature_flag flag)
Definition: map.cpp:4466
ter_id t_rootcellar
Definition: mapdata.cpp:711
furn_id f_minifreezer_on
Definition: mapdata.cpp:1106
furn_id f_fridge_on
Definition: mapdata.cpp:1106

References submap::active_items, f_fridge_on, f_minifreezer_on, furn(), active_item_cache::get_for_processing(), i_at(), process_map_items(), SEEX, SEEY, t_rootcellar, TEMP_FREEZER, TEMP_FRIDGE, TEMP_NORMAL, TEMP_ROOT_CELLAR, ter(), tripoint::x, tripoint::y, and tripoint::z.

Referenced by process_items().

◆ process_items_in_vehicle()

void map::process_items_in_vehicle ( vehicle cur_veh,
submap current_submap 
)
private

Definition at line 4659 of file map.cpp.

4660{
4661 const bool engine_heater_is_on = cur_veh.has_part( "E_HEATER", true ) && cur_veh.engine_on;
4662 for( const vpart_reference &vp : cur_veh.get_any_parts( VPFLAG_FLUIDTANK ) ) {
4663 vp.part().process_contents( vp.pos(), engine_heater_is_on );
4664 }
4665
4666 auto cargo_parts = cur_veh.get_parts_including_carried( VPFLAG_CARGO );
4667 for( const vpart_reference &vp : cargo_parts ) {
4668 process_vehicle_items( cur_veh, vp.part_index() );
4669 }
4670
4671 for( item_reference &active_item_ref : cur_veh.active_items.get_for_processing() ) {
4672 if( empty( cargo_parts ) ) {
4673 return;
4674 } else if( !active_item_ref.item_ref ) {
4675 // The item was destroyed, so skip it.
4676 continue;
4677 }
4678 const auto it = std::find_if( begin( cargo_parts ),
4679 end( cargo_parts ), [&]( const vpart_reference & part ) {
4680 return active_item_ref.location == part.mount();
4681 } );
4682
4683 if( it == end( cargo_parts ) ) {
4684 continue; // Can't find a cargo part matching the active item.
4685 }
4686 const item &target = *active_item_ref.item_ref;
4687 // Find the cargo part and coordinates corresponding to the current active item.
4688 const vehicle_part &pt = it->part();
4689 const tripoint item_loc = it->pos();
4690 auto items = cur_veh.get_items( static_cast<int>( it->part_index() ) );
4691 float it_insulation = 1.0;
4693 if( target.is_food() || target.is_food_container() || target.is_corpse() ) {
4694 const vpart_info &pti = pt.info();
4695 if( engine_heater_is_on ) {
4697 }
4698 // some vehicle parts provide insulation, default is 1
4699 it_insulation = pti.item->insulation_factor;
4700
4701 if( pt.enabled && pti.has_flag( VPFLAG_FRIDGE ) ) {
4702 it_insulation = 1; // ignore fridge insulation if on
4704 } else if( pt.enabled && pti.has_flag( VPFLAG_FREEZER ) ) {
4705 it_insulation = 1; // ignore freezer insulation if on
4707 }
4708 }
4709 if( !process_map_items( items, active_item_ref.item_ref, item_loc, it_insulation, flag ) ) {
4710 // If the item was NOT destroyed, we can skip the remainder,
4711 // which handles fallout from the vehicle being damaged.
4712 continue;
4713 }
4714
4715 // item does not exist anymore, might have been an exploding bomb,
4716 // check if the vehicle is still valid (does exist)
4717 if( !current_submap.contains_vehicle( &cur_veh ) ) {
4718 // Nope, vehicle is not in the vehicle list of the submap,
4719 // it might have moved to another submap (unlikely)
4720 // or be destroyed, anyway it does not need to be processed here
4721 return;
4722 }
4723
4724 // Vehicle still valid, reload the list of cargo parts,
4725 // the list of cargo parts might have changed (imagine a part with
4726 // a low index has been removed by an explosion, all the other
4727 // parts would move up to fill the gap).
4728 cargo_parts = cur_veh.get_any_parts( VPFLAG_CARGO );
4729 }
4730}
bool is_food_container() const
Definition: item.cpp:6488
bool is_corpse() const
Whether this is a corpse item.
Definition: item.cpp:6500
bool contains_vehicle(vehicle *)
Definition: submap.cpp:220
bool engine_on
Definition: vehicle.h:1989
vehicle_part_with_feature_range< std::string > get_parts_including_carried(std::string feature) const
Yields a range of parts of this vehicle that each have the given feature and are not broken or remove...
Definition: vehicle.cpp:2730
bool has_part(const std::string &flag, bool enabled=false) const
Check if vehicle has at least one unbroken part with specified flag.
Definition: vehicle.cpp:2560
active_item_cache active_items
Definition: vehicle.h:1864
vehicle_part_with_feature_range< std::string > get_any_parts(std::string feature) const
Yields a range of parts of this vehicle that each have the given feature and not removed.
Definition: vehicle.cpp:2744
itype_id item
base item for this part
Definition: veh_type.h:152
point mount() const
Returns the mount point: the point in the vehicles own coordinate system.
Definition: vehicle.cpp:6787
@ TEMP_HEATER
Definition: enums.h:44
static void process_vehicle_items(vehicle &cur_veh, int part)
Definition: map.cpp:4481
float insulation_factor
How much insulation this item provides, either as a container, or as a vehicle base part.
Definition: itype.h:1037
const vpart_info & info() const
Get part definition common to all parts of this type.
bool enabled
Definition: vehicle.h:411
@ VPFLAG_FLUIDTANK
Definition: veh_type.h:73
@ VPFLAG_FREEZER
Definition: veh_type.h:58
@ VPFLAG_FRIDGE
Definition: veh_type.h:57

References vehicle::active_items, submap::contains_vehicle(), vehicle_part::enabled, vehicle::engine_on, vehicle::get_any_parts(), active_item_cache::get_for_processing(), vehicle::get_items(), vehicle::get_parts_including_carried(), vpart_info::has_flag(), vehicle::has_part(), vehicle_part::info(), itype::insulation_factor, item::is_corpse(), item::is_food(), item::is_food_container(), vpart_info::item, vpart_position::mount(), process_map_items(), process_vehicle_items(), TEMP_FREEZER, TEMP_FRIDGE, TEMP_HEATER, TEMP_NORMAL, VPFLAG_CARGO, VPFLAG_FLUIDTANK, VPFLAG_FREEZER, and VPFLAG_FRIDGE.

Referenced by process_items_in_vehicles().

◆ process_items_in_vehicles()

void map::process_items_in_vehicles ( submap current_submap)
private

Definition at line 4638 of file map.cpp.

4639{
4640 // a copy, important if the vehicle list changes because a
4641 // vehicle got destroyed by a bomb (an active item!), this list
4642 // won't change, but veh_in_nonant will change.
4643 std::vector<vehicle *> vehicles;
4644 for( const auto &veh : current_submap.vehicles ) {
4645 vehicles.push_back( veh.get() );
4646 }
4647 for( auto &cur_veh : vehicles ) {
4648 if( !current_submap.contains_vehicle( cur_veh ) ) {
4649 // vehicle not in the vehicle list of the nonant, has been
4650 // destroyed (or moved to another nonant?)
4651 // Can't be sure that it still exists, so skip it
4652 continue;
4653 }
4654
4655 process_items_in_vehicle( *cur_veh, current_submap );
4656 }
4657}
void process_items_in_vehicle(vehicle &cur_veh, submap &current_submap)
Definition: map.cpp:4659

References submap::contains_vehicle(), process_items_in_vehicle(), and submap::vehicles.

Referenced by process_items().

◆ produce_sap()

void map::produce_sap ( const tripoint p,
const time_duration time_since_last_actualize 
)
protected

Produce sap on tapped maple trees.

Parameters
pLocation of tapped tree
time_since_last_actualizeTime since this function has been called the last time.

Definition at line 7256 of file map.cpp.

7257{
7258 if( time_since_last_actualize <= 0_turns ) {
7259 return;
7260 }
7261
7262 if( t_tree_maple_tapped != ter( p ) ) {
7263 return;
7264 }
7265
7266 // Amount of maple sap liters produced per season per tap
7267 static const int maple_sap_per_season = 56;
7268
7269 // How many turns to produce 1 charge (250 ml) of sap?
7270 const time_duration producing_length = 0.75 * calendar::season_length();
7271
7272 const time_duration turns_to_produce = producing_length / ( maple_sap_per_season * 4 );
7273
7274 // How long of this time_since_last_actualize have we been in the producing period (late winter, early spring)?
7275 time_duration time_producing = 0_turns;
7276
7277 if( time_since_last_actualize >= calendar::year_length() ) {
7278 time_producing = producing_length;
7279 } else {
7280 // We are only producing sap on the intersection with the sap producing season.
7281 const time_duration early_spring_end = 0.5f * calendar::season_length();
7282 const time_duration late_winter_start = 3.75f * calendar::season_length();
7283
7284 const time_point last_actualize = calendar::turn - time_since_last_actualize;
7285 const time_duration last_actualize_tof = time_past_new_year( last_actualize );
7286 bool last_producing = (
7287 last_actualize_tof >= late_winter_start ||
7288 last_actualize_tof < early_spring_end
7289 );
7290 const time_duration current_tof = time_past_new_year( calendar::turn );
7291 bool current_producing = (
7292 current_tof >= late_winter_start ||
7293 current_tof < early_spring_end
7294 );
7295
7296 const time_duration non_producing_length = 3.25 * calendar::season_length();
7297
7298 if( last_producing && current_producing ) {
7299 if( time_since_last_actualize < non_producing_length ) {
7300 time_producing = time_since_last_actualize;
7301 } else {
7302 time_producing = time_since_last_actualize - non_producing_length;
7303 }
7304 } else if( !last_producing && !current_producing ) {
7305 if( time_since_last_actualize > non_producing_length ) {
7306 time_producing = time_since_last_actualize - non_producing_length;
7307 }
7308 } else if( last_producing && !current_producing ) {
7309 // We hit the end of early spring
7310 if( last_actualize_tof < early_spring_end ) {
7311 time_producing = early_spring_end - last_actualize_tof;
7312 } else {
7313 time_producing = calendar::year_length() - last_actualize_tof + early_spring_end;
7314 }
7315 } else if( !last_producing && current_producing ) {
7316 // We hit the start of late winter
7317 if( current_tof >= late_winter_start ) {
7318 time_producing = current_tof - late_winter_start;
7319 } else {
7320 time_producing = 0.25f * calendar::season_length() + current_tof;
7321 }
7322 }
7323 }
7324
7325 int new_charges = roll_remainder( time_producing / turns_to_produce );
7326 // Not enough time to produce 1 charge of sap
7327 if( new_charges <= 0 ) {
7328 return;
7329 }
7330
7331 item sap( "maple_sap", calendar::turn );
7332
7333 // Is there a proper container?
7334 auto items = i_at( p );
7335 for( auto &it : items ) {
7336 if( it.is_bucket() || it.is_watertight_container() ) {
7337 const int capacity = it.get_remaining_capacity_for_liquid( sap, true );
7338 if( capacity > 0 ) {
7339 new_charges = std::min( new_charges, capacity );
7340
7341 // The environment might have poisoned the sap with animals passing by, insects, leaves or contaminants in the ground
7342 sap.poison = one_in( 10 ) ? 1 : 0;
7343 sap.charges = new_charges;
7344
7345 it.fill_with( sap );
7346 }
7347 // Only fill up the first container.
7348 break;
7349 }
7350 }
7351}
time_duration time_past_new_year(const time_point &p)
Definition: calendar.h:502
A point in the game time.
Definition: calendar.h:431
ter_id t_tree_maple_tapped
Definition: mapdata.cpp:681
time_duration year_length()
Definition: calendar.cpp:461
time_duration season_length()
Definition: calendar.cpp:466

References item::charges, i_at(), one_in(), item::poison, roll_remainder(), calendar::season_length(), t_tree_maple_tapped, ter(), time_past_new_year(), calendar::turn, and calendar::year_length().

Referenced by actualize().

◆ propagate_field()

void map::propagate_field ( const tripoint center,
const field_type_id type,
int  amount,
int  max_intensity = 0 
)

Definition at line 1941 of file map_field.cpp.

1943{
1944 using gas_blast = std::pair<float, tripoint>;
1945 std::priority_queue<gas_blast, std::vector<gas_blast>, pair_greater_cmp_first> open;
1946 std::set<tripoint> closed;
1947 open.push( { 0.0f, center } );
1948
1949 const bool not_gas = type.obj().phase != GAS;
1950
1951 while( amount > 0 && !open.empty() ) {
1952 if( closed.count( open.top().second ) ) {
1953 open.pop();
1954 continue;
1955 }
1956
1957 // All points with equal gas intensity should propagate at the same time
1958 std::list<gas_blast> gas_front;
1959 gas_front.push_back( open.top() );
1960 const int cur_intensity = get_field_intensity( open.top().second, type );
1961 open.pop();
1962 while( !open.empty() && get_field_intensity( open.top().second, type ) == cur_intensity ) {
1963 if( closed.count( open.top().second ) == 0 ) {
1964 gas_front.push_back( open.top() );
1965 }
1966
1967 open.pop();
1968 }
1969
1970 int increment = std::max<int>( 1, amount / gas_front.size() );
1971
1972 while( !gas_front.empty() ) {
1973 gas_blast gp = random_entry_removed( gas_front );
1974 closed.insert( gp.second );
1975 const int cur_intensity = get_field_intensity( gp.second, type );
1976 if( cur_intensity < max_intensity ) {
1977 const int bonus = std::min( max_intensity - cur_intensity, increment );
1978 mod_field_intensity( gp.second, type, bonus );
1979 amount -= bonus;
1980 } else {
1981 amount--;
1982 }
1983
1984 if( amount <= 0 ) {
1985 return;
1986 }
1987
1988 static const std::array<int, 8> x_offset = {{ -1, 1, 0, 0, 1, -1, -1, 1 }};
1989 static const std::array<int, 8> y_offset = {{ 0, 0, -1, 1, -1, 1, -1, 1 }};
1990 for( size_t i = 0; i < 8; i++ ) {
1991 tripoint pt = gp.second + point( x_offset[ i ], y_offset[ i ] );
1992 if( closed.count( pt ) > 0 ) {
1993 continue;
1994 }
1995
1996 if( impassable( pt ) && ( not_gas || !has_flag( TFLAG_PERMEABLE, pt ) ) ) {
1997 closed.insert( pt );
1998 continue;
1999 }
2000 if( !obstructed_by_vehicle_rotation( gp.second, pt ) ) {
2001 open.push( { static_cast<float>( rl_dist( center, pt ) ), pt } );
2002 }
2003 }
2004 }
2005 }
2006}
@ GAS
Definition: enums.h:175
Greater-than comparison operator; required by the sort interface.
Definition: cata_utility.h:16

References center, GAS, get_field_intensity(), has_flag(), impassable(), mod_field_intensity(), obstructed_by_vehicle_rotation(), open(), random_entry_removed(), rl_dist(), TFLAG_PERMEABLE, and type.

Referenced by computer_session::action_irradiator(), and emit_field().

◆ propagate_suspension_check()

void map::propagate_suspension_check ( const tripoint point)

Checks surrounding tiles for suspension, and has them check for collapse.

!!Should only be called after the tile at this point has been destroyed!!

Definition at line 2954 of file map.cpp.

2955{
2956 for( const tripoint &neighbor : points_in_radius( point, 1 ) ) {
2957 if( neighbor != point && has_flag( TFLAG_SUSPENDED, neighbor ) ) {
2958 collapse_invalid_suspension( neighbor );
2959 }
2960 }
2961}

References collapse_invalid_suspension(), has_flag(), points_in_radius(), and TFLAG_SUSPENDED.

Referenced by bash_ter_success(), collapse_at(), and collapse_invalid_suspension().

◆ put_items_from_loc()

std::vector< item * > map::put_items_from_loc ( const item_group_id loc,
const tripoint p,
const time_point turn = calendar::start_of_cataclysm 
)

Place items from an item group at p.

Places as much items as the item group says. (Most item groups are distributions and will only create one item.)

Parameters
locCurrent location of items
pDestination of items
turnThe birthday that the created items shall have.
Returns
Vector of pointers to placed items (can be empty, but no nulls).

Definition at line 5578 of file mapgen.cpp.

5580{
5581 const auto items = item_group::items_from( loc, turn );
5582 return spawn_items( p, items );
5583}

References item_group::items_from(), spawn_items(), and calendar::turn.

Referenced by add_corpse(), activity_handlers::forage_finish(), mapgen_cavern(), MapExtras::mx_corpses(), MapExtras::mx_grave(), MapExtras::mx_mayhem(), MapExtras::mx_minefield(), and place_items().

◆ rad_scorch()

void map::rad_scorch ( const tripoint p,
const time_duration time_since_last_actualize 
)
protected

Radiation-related plant (and fungus?) death.

Definition at line 7353 of file map.cpp.

7354{
7355 const int rads = get_radiation( p );
7356 if( rads == 0 ) {
7357 return;
7358 }
7359
7360 // TODO: More interesting rad scorch chance - base on season length?
7361 if( !x_in_y( 1.0 * rads * rads * time_since_last_actualize, 91_days ) ) {
7362 return;
7363 }
7364
7365 // First destroy the farmable plants (those are furniture)
7366 // TODO: Rad-resistant mutant plants (that produce radioactive fruit)
7367 const furn_t &fid = furn( p ).obj();
7368 if( fid.has_flag( "PLANT" ) ) {
7369 i_clear( p );
7370 furn_set( p, f_null );
7371 }
7372
7373 const ter_id tid = ter( p );
7374 // TODO: De-hardcode this
7375 static const std::map<ter_id, ter_str_id> dies_into {{
7376 {t_grass, ter_str_id( "t_dirt" )},
7377 {t_tree_young, ter_str_id( "t_dirt" )},
7378 {t_tree_pine, ter_str_id( "t_tree_deadpine" )},
7379 {t_tree_birch, ter_str_id( "t_tree_birch_harvested" )},
7380 {t_tree_willow, ter_str_id( "t_tree_willow_harvested" )},
7381 {t_tree_hickory, ter_str_id( "t_tree_hickory_dead" )},
7382 {t_tree_hickory_harvested, ter_str_id( "t_tree_hickory_dead" )},
7383 }};
7384
7385 const auto iter = dies_into.find( tid );
7386 if( iter != dies_into.end() ) {
7387 ter_set( p, iter->second );
7388 return;
7389 }
7390
7391 const ter_t &tr = tid.obj();
7392 if( tr.has_flag( "SHRUB" ) ) {
7393 ter_set( p, t_dirt );
7394 } else if( tr.has_flag( "TREE" ) ) {
7395 ter_set( p, ter_str_id( "t_tree_dead" ) );
7396 }
7397}
int get_radiation(const tripoint &p) const
Definition: map.cpp:4034
ter_id t_tree_hickory_harvested
Definition: mapdata.cpp:682
ter_id t_tree_willow
Definition: mapdata.cpp:681
ter_id t_tree_birch
Definition: mapdata.cpp:681
ter_id t_tree_pine
Definition: mapdata.cpp:681
ter_id t_tree_young
Definition: mapdata.cpp:677
ter_id t_tree_hickory
Definition: mapdata.cpp:682
string_id< ter_t > ter_str_id
Definition: mapdata.h:24

References f_null, furn(), furn_set(), get_radiation(), map_data_common_t::has_flag(), i_clear(), int_id< T >::obj(), t_dirt, t_grass, t_tree_birch, t_tree_hickory, t_tree_hickory_harvested, t_tree_pine, t_tree_willow, t_tree_young, ter(), ter_set(), and x_in_y().

Referenced by actualize().

◆ random_outdoor_tile()

point map::random_outdoor_tile ( )

Definition at line 2741 of file map.cpp.

2742{
2743 std::vector<point> options;
2744 for( const tripoint &p : points_on_zlevel() ) {
2745 if( is_outside( p.xy() ) ) {
2746 options.push_back( p.xy() );
2747 }
2748 }
2750}
std::string options()
Definition: path_info.cpp:238

References is_outside(), PATH_INFO::options(), point_north_west, points_on_zlevel(), and random_entry().

◆ ranged_target_size()

double map::ranged_target_size ( const tripoint p) const

Size of map objects at p for purposes of ranged combat.

Size is in percentage of tile: if 1.0, all attacks going through tile should hit map objects on it, if 0.0 there is nothing to be hit (air/water).

Definition at line 1955 of file map.cpp.

1956{
1957 if( impassable( p ) ) {
1958 return 1.0;
1959 }
1960
1961 if( !has_floor( p ) ) {
1962 return 0.0;
1963 }
1964
1965 // TODO: Handle cases like shrubs, trees, furniture, sandbags...
1966 return 0.1;
1967}

References has_floor(), and impassable().

Referenced by projectile_attack().

◆ reachable_flood_steps()

void map::reachable_flood_steps ( std::vector< tripoint > &  reachable_pts,
const tripoint f,
int  range,
int  cost_min,
int  cost_max 
) const

Populates a vector of points that are reachable within a number of steps from a point.

It could be generalized to take advantage of z levels, but would need some additional code to detect whether a valid transition was on a tile.

Does the following:

  1. Checks if a point is reachable using a flood fill and if it is, adds it to a vector.

Definition at line 6297 of file map.cpp.

6299{
6300 struct pq_item {
6301 int dist;
6302 int ndx;
6303 };
6304 struct pq_item_comp {
6305 bool operator()( const pq_item &left, const pq_item &right ) {
6306 return left.dist > right.dist;
6307 }
6308 };
6309 using PQ_type = std::priority_queue< pq_item, std::vector<pq_item>, pq_item_comp>;
6310
6311 // temp buffer for grid
6312 const int grid_dim = range * 2 + 1;
6313 // init to -1 as "not visited yet"
6314 std::vector< int > t_grid( static_cast<size_t>( grid_dim * grid_dim ), -1 );
6315 const tripoint origin_offset = {range, range, 0};
6316 const int initial_visit_distance = range * range; // Large unreachable value
6317
6318 // Fill positions that are visitable with initial_visit_distance
6319 for( const tripoint &p : points_in_radius( f, range ) ) {
6320 const tripoint tp = { p.xy(), f.z };
6321 const int tp_cost = move_cost( tp );
6322 // rejection conditions
6323 if( tp_cost < cost_min || tp_cost > cost_max || !has_floor_or_support( tp ) ) {
6324 continue;
6325 }
6326 // set initial cost for grid point
6327 tripoint origin_relative = tp - f;
6328 origin_relative += origin_offset;
6329 int ndx = origin_relative.x + origin_relative.y * grid_dim;
6330 t_grid[ ndx ] = initial_visit_distance;
6331 }
6332
6333 auto gen_neighbors = []( const pq_item & elem, int grid_dim, pq_item * neighbors ) {
6334 // Up to 8 neighbors
6335 int new_cost = elem.dist + 1;
6336 // *INDENT-OFF*
6337 int ox[8] = {
6338 -1, 0, 1,
6339 -1, 1,
6340 -1, 0, 1
6341 };
6342 int oy[8] = {
6343 -1, -1, -1,
6344 0, 0,
6345 1, 1, 1
6346 };
6347 // *INDENT-ON*
6348
6349 point e( elem.ndx % grid_dim, elem.ndx / grid_dim );
6350 for( int i = 0; i < 8; ++i ) {
6351 point n( e + point( ox[i], oy[i] ) );
6352
6353 int ndx = n.x + n.y * grid_dim;
6354 neighbors[i] = { new_cost, ndx };
6355 }
6356 };
6357
6358 PQ_type pq( pq_item_comp{} );
6359 pq_item first_item{ 0, range + range * grid_dim };
6360 pq.push( first_item );
6361 pq_item neighbor_elems[8];
6362
6363 while( !pq.empty() ) {
6364 const pq_item item = pq.top();
6365 pq.pop();
6366
6367 if( t_grid[ item.ndx ] == initial_visit_distance ) {
6368 t_grid[ item.ndx ] = item.dist;
6369 if( item.dist + 1 < range ) {
6370 gen_neighbors( item, grid_dim, neighbor_elems );
6371 for( pq_item neighbor_elem : neighbor_elems ) {
6372 pq.push( neighbor_elem );
6373 }
6374 }
6375 }
6376 }
6377 std::vector<char> o_grid( static_cast<size_t>( grid_dim * grid_dim ), 0 );
6378 for( int y = 0, ndx = 0; y < grid_dim; ++y ) {
6379 for( int x = 0; x < grid_dim; ++x, ++ndx ) {
6380 if( t_grid[ ndx ] != -1 && t_grid[ ndx ] < initial_visit_distance ) {
6381 // set self and neighbors to 1
6382 for( int dy = -1; dy <= 1; ++dy ) {
6383 for( int dx = -1; dx <= 1; ++dx ) {
6384 int tx = dx + x;
6385 int ty = dy + y;
6386
6387 if( tx >= 0 && tx < grid_dim && ty >= 0 && ty < grid_dim ) {
6388 o_grid[ tx + ty * grid_dim ] = 1;
6389 }
6390 }
6391 }
6392 }
6393 }
6394 }
6395
6396 // Now go over again to pull out all of the reachable points
6397 for( int y = 0, ndx = 0; y < grid_dim; ++y ) {
6398 for( int x = 0; x < grid_dim; ++x, ++ndx ) {
6399 if( o_grid[ ndx ] ) {
6400 tripoint t = f - origin_offset + tripoint{ x, y, 0 };
6401 reachable_pts.push_back( t );
6402 }
6403 }
6404 }
6405}

References has_floor_or_support(), left, move_cost(), points_in_radius(), right, point::x, tripoint::x, tripoint::xy(), point::y, tripoint::y, and tripoint::z.

Referenced by inventory::form_from_map(), and use_charges().

◆ register_vehicle_zone()

void map::register_vehicle_zone ( vehicle veh,
int  zlev 
)

Definition at line 957 of file map.cpp.

958{
959 auto &ch = get_cache( zlev );
960 ch.zone_vehicles.insert( veh );
961}

References get_cache().

Referenced by zone_manager::create_vehicle_loot_zone(), and zone_manager::revert_vzones().

◆ remove_field()

void map::remove_field ( const tripoint p,
const field_type_id field_to_remove 
)

Remove field entry at xy, ignored if the field entry is not present.

Definition at line 5465 of file map.cpp.

5466{
5467 if( !inbounds( p ) ) {
5468 return;
5469 }
5470
5471 point l;
5472 submap *const current_submap = get_submap_at( p, l );
5473
5474 if( current_submap->get_field( l ).remove_field( field_to_remove ) ) {
5475 // Only adjust the count if the field actually existed.
5476 if( !--current_submap->field_count ) {
5477 get_cache( p.z ).field_cache.set( static_cast<size_t>( p.x / SEEX + ( (
5478 p.y / SEEX ) * MAPSIZE ) ) );
5479 }
5480 const auto &fdata = field_to_remove.obj();
5481 if( fdata.dirty_transparency_cache || !fdata.is_transparent() ) {
5484 }
5485 if( fdata.is_dangerous() ) {
5487 }
5488 }
5489}

References level_cache::field_cache, submap::field_count, get_cache(), submap::get_field(), get_submap_at(), inbounds(), MAPSIZE, int_id< T >::obj(), field::remove_field(), SEEX, set_pathfinding_cache_dirty(), set_seen_cache_dirty(), set_transparency_cache_dirty(), tripoint::x, tripoint::y, and tripoint::z.

Referenced by computer_session::action_deactivate_shock_vent(), bash_field(), editmap::edit_fld(), iexamine::fireplace(), game::grabbed_furn_move(), MapExtras::mx_house_spider(), MapExtras::mx_spider(), game::process_artifact(), set_field_intensity(), shoot(), smash(), spell_move(), and game::walk_move().

◆ remove_rotten_items()

template<typename Container >
void map::remove_rotten_items ( Container &  items,
const tripoint p 
)
protected

Go through the list of items, update their rotten status and remove items that have rotten away completely.

Parameters
itemsitems to remove
pThe point on this map where the items are, used for rot calculation.

Definition at line 7102 of file map.cpp.

7103{
7104 for( auto it = items.begin(); it != items.end(); ) {
7105 if( it->has_rotten_away( pnt ) ) {
7106 if( it->is_comestible() ) {
7107 rotten_item_spawn( *it, pnt );
7108 }
7109 it = i_rem( pnt, it );
7110 } else {
7111 ++it;
7112 }
7113 }
7114}

References i_rem(), and rotten_item_spawn().

Referenced by actualize().

◆ remove_submap_camp()

void map::remove_submap_camp ( const tripoint p)

Definition at line 5580 of file map.cpp.

5581{
5582 get_submap_at( p )->camp.reset();
5583}

References submap::camp, and get_submap_at().

Referenced by basecamp::abandon_camp(), and game::validate_camps().

◆ remove_trap()

void map::remove_trap ( const tripoint p)

Definition at line 5273 of file map.cpp.

5274{
5275 if( !inbounds( p ) ) {
5276 return;
5277 }
5278
5279 point l;
5280 submap *const current_submap = get_submap_at( p, l );
5281
5282 trap_id tid = current_submap->get_trap( l );
5283 if( tid != tr_null ) {
5284 if( g != nullptr && this == &get_map() ) {
5285 g->u.add_known_trap( p, tr_null.obj() );
5286 }
5287
5288 current_submap->set_trap( l, tr_null );
5289 auto &traps = traplocs[tid.to_i()];
5290 const auto iter = std::find( traps.begin(), traps.end(), p );
5291 if( iter != traps.end() ) {
5292 traps.erase( iter );
5293 }
5294 }
5295}
void set_trap(const point &p, trap_id trap)
Definition: submap.h:77

References detail::find(), g, get_map(), get_submap_at(), submap::get_trap(), inbounds(), int_id< T >::obj(), submap::set_trap(), int_id< T >::to_i(), tr_null, and traplocs.

Referenced by complete_construction(), vehicle::handle_trap(), trapfunc::map_regen(), mremove_trap(), trap::on_disarmed(), game::process_artifact(), and trap_set().

◆ reset_vehicle_cache()

void map::reset_vehicle_cache ( )

Definition at line 254 of file map.cpp.

255{
258
259 // Cache all vehicles
260 const int zmin = zlevels ? -OVERMAP_DEPTH : abs_sub.z;
261 const int zmax = zlevels ? OVERMAP_HEIGHT : abs_sub.z;
262 for( int zlev = zmin; zlev <= zmax; zlev++ ) {
263 auto &ch = get_cache( zlev );
264 for( const auto &elem : ch.vehicle_list ) {
265 elem->adjust_zlevel( 0, tripoint_zero );
266 add_vehicle_to_cache( elem );
267 }
268 }
269}
void clear_vehicle_cache()
Definition: map.cpp:313

References abs_sub, add_vehicle_to_cache(), clear_vehicle_cache(), get_cache(), last_full_vehicle_list_dirty, OVERMAP_DEPTH, OVERMAP_HEIGHT, tripoint_zero, tripoint::z, and zlevels.

Referenced by veh_interact::complete_vehicle(), detach_vehicle(), editmap::draw_main_ui_overlay(), load(), loadn(), editmap::mapgen_preview(), editmap::mapgen_veh_destroy(), rotate(), shift(), and vehicle::use_bike_rack().

◆ restock_fruits()

void map::restock_fruits ( const tripoint p,
const time_duration time_since_last_actualize 
)
protected

Try to grow fruits on static plants (not planted by the player)

Parameters
pPlace to restock
time_since_last_actualizeTime since this function has been called the last time.

Definition at line 7242 of file map.cpp.

7243{
7244 const auto &ter = this->ter( p ).obj();
7245 if( !ter.has_flag( TFLAG_HARVESTED ) ) {
7246 return; // Already harvestable. Do nothing.
7247 }
7248 // Make it harvestable again if the last actualization was during a different season or year.
7249 const time_point last_touched = calendar::turn - time_since_last_actualize;
7250 if( season_of_year( calendar::turn ) != season_of_year( last_touched ) ||
7251 time_since_last_actualize >= calendar::season_length() ) {
7252 ter_set( p, ter.transforms_into );
7253 }
7254}
season_type season_of_year(const time_point &p)
Definition: calendar.cpp:547

References int_id< T >::obj(), calendar::season_length(), season_of_year(), ter(), ter_set(), TFLAG_HARVESTED, and calendar::turn.

Referenced by actualize(), and saven().

◆ restore_vision_transparency_cache()

void map::restore_vision_transparency_cache ( const tripoint center,
int  target_z,
float(&)  vision_restore_cache[9],
bool(&)  blocked_restore_cache[8] 
)
protected

Definition at line 1352 of file lightmap.cpp.

1354{
1355 auto &map_cache = get_cache( target_z );
1356 float ( &transparency_cache )[MAPSIZE_X][MAPSIZE_Y] = map_cache.transparency_cache;
1357 diagonal_blocks( &blocked_cache )[MAPSIZE_X][MAPSIZE_Y] = map_cache.vehicle_obscured_cache;
1358
1359 int i = 0;
1360 for( const point &adjacent : eight_adjacent_offsets ) {
1361 const tripoint p = center + adjacent;
1362 if( !inbounds( p ) ) {
1363 continue;
1364 }
1365 transparency_cache[p.x][p.y] = vision_restore_cache[i];
1366
1367 if( blocked_restore_cache[i] ) {
1368 bool &relevant_blocked = adjacent == point_north_east ? blocked_cache[center.x][center.y].ne :
1369 adjacent == point_south_east ? blocked_cache[p.x][p.y].nw :
1370 adjacent == point_south_west ? blocked_cache[p.x][p.y].ne :
1371 /* point_north_west */ blocked_cache[center.x][center.y].nw;
1372 relevant_blocked = false;
1373 }
1374
1375 i++;
1376 }
1377 transparency_cache[center.x][center.y] = vision_restore_cache[8];
1378}

References center, eight_adjacent_offsets, get_cache(), inbounds(), MAPSIZE_X, MAPSIZE_Y, point_north_east, point_south_east, point_south_west, tripoint::x, and tripoint::y.

Referenced by build_seen_cache().

◆ rotate()

void map::rotate ( int  turns,
bool  setpos_safe = false 
)

Rotates this map, and all of its contents, by the specified multiple of 90 degrees.

Parameters
turnsHow many 90-degree turns to rotate the map.

Definition at line 5805 of file mapgen.cpp.

5806{
5807
5808 //Handle anything outside the 1-3 range gracefully; rotate(0) is a no-op.
5809 turns = turns % 4;
5810 if( turns == 0 ) {
5811 return;
5812 }
5813
5814 real_coords rc;
5815 const tripoint &abs_sub = get_abs_sub();
5816 rc.fromabs( point( abs_sub.x * SEEX, abs_sub.y * SEEY ) );
5817
5818 // TODO: This radius can be smaller - how small?
5819 const int radius = HALF_MAPSIZE + 3;
5820 // uses submap coordinates
5821 // TODO: fix point types
5822 const std::vector<shared_ptr_fast<npc>> npcs =
5824 for( const shared_ptr_fast<npc> &i : npcs ) {
5825 npc &np = *i;
5826 const tripoint sq = np.global_square_location();
5827 const point local_sq = getlocal( sq ).xy();
5828
5829 real_coords np_rc;
5830 np_rc.fromabs( sq.xy() );
5831 // Note: We are rotating the entire overmap square (2x2 of submaps)
5832 if( np_rc.om_pos != rc.om_pos || sq.z != abs_sub.z ) {
5833 continue;
5834 }
5835
5836 // OK, this is ugly: we remove the NPC from the whole map
5837 // Then we place it back from scratch
5838 // It could be rewritten to utilize the fact that rotation shouldn't cross overmaps
5839
5840 point old( np_rc.sub_pos );
5841 if( np_rc.om_sub.x % 2 != 0 ) {
5842 old.x += SEEX;
5843 }
5844 if( np_rc.om_sub.y % 2 != 0 ) {
5845 old.y += SEEY;
5846 }
5847
5848 const point new_pos = old .rotate( turns, { SEEX * 2, SEEY * 2 } );
5849 if( setpos_safe ) {
5850 // setpos can't be used during mapgen, but spawn_at_precise clips position
5851 // to be between 0-11,0-11 and teleports NPCs when used inside of update_mapgen
5852 // calls
5853 const tripoint new_global_sq = sq - local_sq + new_pos;
5854 np.setpos( get_map().getlocal( new_global_sq ) );
5855 } else {
5856 // OK, this is ugly: we remove the NPC from the whole map
5857 // Then we place it back from scratch
5858 // It could be rewritten to utilize the fact that rotation shouldn't cross overmaps
5860 np.spawn_at_precise( { abs_sub.xy() }, { new_pos, abs_sub.z } );
5862 }
5863 }
5864
5867
5868 // Move the submaps around.
5869 if( turns == 2 ) {
5872 } else {
5873 point p;
5874 submap tmp;
5875
5877
5878 for( int k = 0; k < 4; ++k ) {
5879 p = p.rotate( turns, { 2, 2 } );
5881 }
5882 }
5883
5884 // Then rotate them and recalculate vehicle positions.
5885 for( int j = 0; j < 2; ++j ) {
5886 for( int i = 0; i < 2; ++i ) {
5887 point p( i, j );
5888 auto sm = get_submap_at_grid( p );
5889
5890 sm->rotate( turns );
5891
5892 for( auto &veh : sm->vehicles ) {
5893 veh->sm_pos = tripoint( p, abs_sub.z );
5894 }
5895
5897 }
5898 }
5900
5901 // rotate zones
5903 mgr.rotate_zones( *this, turns );
5904}
shared_ptr_fast< npc > npc_ptr
Definition: basecamp.h:46
character_id getID() const
Definition: character.cpp:477
void clear_vehicle_list(int zlev)
Definition: map.cpp:331
void spawn_at_precise(const point &submap_offset, const tripoint &square)
As spawn_at, but also sets position within the submap.
Definition: npc.cpp:729
void setpos(const tripoint &pos) override
Note: this places NPC on a given position in CURRENT MAP coordinates.
Definition: npc.cpp:681
tripoint global_square_location() const override
Global position, expressed in map square coordinate system (the most detailed coordinate system),...
Definition: npc.cpp:739
std::vector< shared_ptr_fast< npc > > get_npcs_near(const tripoint_abs_sm &p, int radius)
Get all npcs in a area with given radius around given central point.
shared_ptr_fast< npc > remove_npc(const character_id &id)
Find npc by id and if found, erase it from the npc list and return it ( or return nullptr if not foun...
void rotate_zones(map &target_map, int turns)
Definition: clzones.cpp:1052
coords::coord_point< tripoint, coords::origin::abs, coords::sm > tripoint_abs_sm
Definition: coordinates.h:490
static constexpr int HALF_MAPSIZE
void swap(colony< element_type, element_allocator_type, element_skipfield_type > &a, colony< element_type, element_allocator_type, element_skipfield_type > &b) COLONY_NOEXCEPT_SWAP(element_allocator_type)
Swaps colony A's contents with that of colony B.
Definition: colony.h:3496
point rotate(int turns, const point &dim={ 1, 1 }) const
Rotate point clockwise.
Definition: point.h:89
point om_sub
Definition: coordinates.h:638
void fromabs(const point &abs)
Definition: coordinates.h:646
point om_pos
Definition: coordinates.h:637
point sub_pos
Definition: coordinates.h:635

References abs_sub, clear_vehicle_cache(), clear_vehicle_list(), real_coords::fromabs(), get_abs_sub(), zone_manager::get_manager(), get_map(), overmapbuffer::get_npcs_near(), get_submap_at_grid(), Character::getID(), getlocal(), npc::global_square_location(), HALF_MAPSIZE, overmapbuffer::insert_npc(), real_coords::om_pos, real_coords::om_sub, overmap_buffer, point_east, point_south, point_south_east, point_zero, overmapbuffer::remove_npc(), reset_vehicle_cache(), point::rotate(), zone_manager::rotate_zones(), SEEX, SEEY, npc::setpos(), coords::sm, npc::spawn_at_precise(), real_coords::sub_pos, cata::swap(), update_vehicle_list(), point::x, tripoint::x, tripoint::xy(), point::y, tripoint::y, and tripoint::z.

Referenced by draw_connections(), draw_lab(), draw_office_tower(), draw_triffid(), mapgen_function_json::generate(), mapgen_ants_curved(), mapgen_ants_straight(), mapgen_ants_tee(), mapgen_forest_trail_curved(), mapgen_forest_trail_straight(), mapgen_forest_trail_tee(), mapgen_highway(), mapgen_parking_lot(), editmap::mapgen_preview(), mapgen_railroad(), mapgen_railroad_bridge(), mapgen_river_curved(), mapgen_river_curved_not(), mapgen_river_straight(), mapgen_road(), mapgen_rotate(), mapgen_sewer_curved(), mapgen_sewer_straight(), mapgen_sewer_tee(), mapgen_subway(), and update_mapgen_function_json::update_map().

◆ rotten_item_spawn()

void map::rotten_item_spawn ( const item item,
const tripoint p 
)

Checks to see if the item that is rotting away generates a creature when it does.

Parameters
itemitem that is spawning creatures
pThe point on this map where the item is and creature will be

Definition at line 7116 of file map.cpp.

7117{
7118 if( g->critter_at( pnt ) != nullptr ) {
7119 return;
7120 }
7121 const auto &comest = item.get_comestible();
7122 mongroup_id mgroup = comest->rot_spawn;
7123 if( !mgroup ) {
7124 return;
7125 }
7126 const int chance = static_cast<int>( comest->rot_spawn_chance *
7127 get_option<float>( "CARRION_SPAWNRATE" ) );
7128 if( rng( 0, 100 ) < chance ) {
7130 add_spawn( spawn_details.name, 1, pnt, false );
7131 if( g->u.sees( pnt ) ) {
7132 if( item.is_seed() ) {
7133 add_msg( m_warning, _( "Something has crawled out of the %s plants!" ), item.get_plant_name() );
7134 } else {
7135 add_msg( m_warning, _( "Something has crawled out of the %s!" ), item.tname() );
7136 }
7137 }
7138 }
7139}
const cata::value_ptr< islot_comestible > & get_comestible() const
Definition: item.cpp:9991
std::string get_plant_name() const
The name of the plant as it appears in the various informational menus.
Definition: item.cpp:9660
bool is_seed() const
Whether this is actually a seed, the seed functions won't be of much use for non-seeds.
Definition: item.cpp:9641

References _, add_msg(), add_spawn(), g, item::get_comestible(), item::get_plant_name(), MonsterGroupManager::GetResultFromGroup(), item::is_seed(), m_warning, MonsterGroupResult::name, rng(), and item::tname().

Referenced by grow_plant(), item::process_internal(), and remove_rotten_items().

◆ route()

std::vector< tripoint > map::route ( const tripoint f,
const tripoint t,
const pathfinding_settings settings,
const std::set< tripoint > &  pre_closed = {{ }} 
) const

Calculate the best path using A*.

Parameters
fThe source location from which to path.
tThe destination to which to path.
settingsStructure describing pathfinding parameters.
pre_closedNever path through those points. They can still be the source or the destination.

Definition at line 194 of file pathfinding.cpp.

197{
198 /* TODO: If the origin or destination is out of bound, figure out the closest
199 * in-bounds point and go to that, then to the real origin/destination.
200 */
201 std::vector<tripoint> ret;
202
203 if( f == t || !inbounds( f ) ) {
204 return ret;
205 }
206
207 if( !inbounds( t ) ) {
208 tripoint clipped = t;
209 clip_to_bounds( clipped );
210 return route( f, clipped, settings, pre_closed );
211 }
212 // First, check for a simple straight line on flat ground
213 // Except when the line contains a pre-closed tile - we need to do regular pathing then
214 static const auto non_normal = PF_SLOW | PF_WALL | PF_VEHICLE | PF_TRAP | PF_SHARP;
215 if( f.z == t.z ) {
216 const auto line_path = line_to( f, t );
217 const auto &pf_cache = get_pathfinding_cache_ref( f.z );
218 // Check all points for any special case (including just hard terrain)
219 if( !( pf_cache.special[f.x][f.y] & non_normal ) &&
220 std::all_of( line_path.begin(), line_path.end(), [&pf_cache]( const tripoint & p ) {
221 return !( pf_cache.special[p.x][p.y] & non_normal );
222 } ) ) {
223 const std::set<tripoint> sorted_line( line_path.begin(), line_path.end() );
224
225 if( is_disjoint( sorted_line, pre_closed ) ) {
226 return line_path;
227 }
228 }
229 }
230
231 // If expected path length is greater than max distance, allow only line path, like above
232 if( rl_dist( f, t ) > settings.max_dist ) {
233 return ret;
234 }
235
236 int max_length = settings.max_length;
237 int bash = settings.bash_strength;
238 int climb_cost = settings.climb_cost;
239 bool doors = settings.allow_open_doors;
240 bool trapavoid = settings.avoid_traps;
241 bool roughavoid = settings.avoid_rough_terrain;
242 bool sharpavoid = settings.avoid_sharp;
243
244 const int pad = 16; // Should be much bigger - low value makes pathfinders dumb!
245 int minx = std::min( f.x, t.x ) - pad;
246 int miny = std::min( f.y, t.y ) - pad;
247 // TODO: Make this way bigger
248 int minz = std::min( f.z, t.z );
249 int maxx = std::max( f.x, t.x ) + pad;
250 int maxy = std::max( f.y, t.y ) + pad;
251 // Same TODO: as above
252 int maxz = std::max( f.z, t.z );
253 clip_to_bounds( minx, miny, minz );
254 clip_to_bounds( maxx, maxy, maxz );
255
256 pathfinder pf( point( minx, miny ), point( maxx, maxy ) );
257 // Make NPCs not want to path through player
258 // But don't make player pathing stop working
259 for( const auto &p : pre_closed ) {
260 if( p.x >= minx && p.x < maxx && p.y >= miny && p.y < maxy ) {
261 pf.close_point( p );
262 }
263 }
264
265 // Start and end must not be closed
266 pf.unclose_point( f );
267 pf.unclose_point( t );
268 pf.add_point( 0, 0, f, f );
269
270 bool done = false;
271
272 do {
273 auto cur = pf.get_next();
274
275 const int parent_index = flat_index( cur );
276 auto &layer = pf.get_layer( cur.z );
277 auto &cur_state = layer.state[parent_index];
278 if( cur_state == ASL_CLOSED ) {
279 continue;
280 }
281
282 if( layer.gscore[parent_index] > max_length ) {
283 // Shortest path would be too long, return empty vector
284 return std::vector<tripoint>();
285 }
286
287 if( cur == t ) {
288 done = true;
289 break;
290 }
291
292 cur_state = ASL_CLOSED;
293
294 const auto &pf_cache = get_pathfinding_cache_ref( cur.z );
295 const auto cur_special = pf_cache.special[cur.x][cur.y];
296
297 int cur_part;
298 const vehicle *cur_veh = veh_at_internal( cur, cur_part );
299
300 // 7 3 5
301 // 1 . 2
302 // 6 4 8
303 constexpr std::array<int, 8> x_offset{{ -1, 1, 0, 0, 1, -1, -1, 1 }};
304 constexpr std::array<int, 8> y_offset{{ 0, 0, -1, 1, -1, 1, -1, 1 }};
305 for( size_t i = 0; i < 8; i++ ) {
306 const tripoint p( cur.x + x_offset[i], cur.y + y_offset[i], cur.z );
307 const int index = flat_index( p );
308
309 // TODO: Remove this and instead have sentinels at the edges
310 if( p.x < minx || p.x >= maxx || p.y < miny || p.y >= maxy ) {
311 continue;
312 }
313
314 if( layer.state[index] == ASL_CLOSED ) {
315 continue;
316 }
317
318 int part = -1;
319 const vehicle *veh = veh_at_internal( p, part );
320 if( cur_veh &&
321 !cur_veh->allowed_move( cur_veh->tripoint_to_mount( cur ), cur_veh->tripoint_to_mount( p ) ) ) {
322 //Trying to squeeze through a vehicle hole, skip this movement but don't close the tile as other paths may lead to it
323 continue;
324 }
325
326 if( veh && veh != cur_veh &&
327 !veh->allowed_move( veh->tripoint_to_mount( cur ), veh->tripoint_to_mount( p ) ) ) {
328 //Same as above but moving into rather than out of a vehicle
329 continue;
330 }
331
332 // Penalize for diagonals or the path will look "unnatural"
333 int newg = layer.gscore[parent_index] + ( ( cur.x != p.x && cur.y != p.y ) ? 1 : 0 );
334
335 const auto p_special = pf_cache.special[p.x][p.y];
336 // TODO: De-uglify, de-huge-n
337 if( !( p_special & non_normal ) ) {
338 // Boring flat dirt - the most common case above the ground
339 newg += 2;
340 } else {
341 if( roughavoid ) {
342 layer.state[index] = ASL_CLOSED; // Close all rough terrain tiles
343 continue;
344 }
345
346 const maptile &tile = maptile_at_internal( p );
347 const auto &terrain = tile.get_ter_t();
348 const auto &furniture = tile.get_furn_t();
349
350 const int cost = move_cost_internal( furniture, terrain, veh, part );
351 // Don't calculate bash rating unless we intend to actually use it
352 const int rating = ( bash == 0 || cost != 0 ) ? -1 :
353 bash_rating_internal( bash, furniture, terrain, false, veh, part );
354
355 if( cost == 0 && rating <= 0 && ( !doors || !terrain.open || !furniture.open ) && veh == nullptr &&
356 climb_cost <= 0 ) {
357 layer.state[index] = ASL_CLOSED; // Close it so that next time we won't try to calculate costs
358 continue;
359 }
360
361 newg += cost;
362 if( cost == 0 ) {
363 if( climb_cost > 0 && p_special & PF_CLIMBABLE ) {
364 // Climbing fences
365 newg += climb_cost;
366 } else if( doors && ( terrain.open || furniture.open ) &&
367 ( !terrain.has_flag( "OPENCLOSE_INSIDE" ) || !furniture.has_flag( "OPENCLOSE_INSIDE" ) ||
368 !is_outside( cur ) ) ) {
369 // Only try to open INSIDE doors from the inside
370 // To open and then move onto the tile
371 newg += 4;
372 } else if( veh != nullptr ) {
373 const auto vpobst = vpart_position( const_cast<vehicle &>( *veh ), part ).obstacle_at_part();
374 part = vpobst ? vpobst->part_index() : -1;
375 int dummy = -1;
376 if( doors && veh->part_flag( part, VPFLAG_OPENABLE ) &&
377 ( !veh->part_flag( part, "OPENCLOSE_INSIDE" ) ||
378 veh_at_internal( cur, dummy ) == veh ) ) {
379 // Handle car doors, but don't try to path through curtains
380 newg += 10; // One turn to open, 4 to move there
381 } else if( part >= 0 && bash > 0 ) {
382 // Car obstacle that isn't a door
383 // TODO: Account for armor
384 int hp = veh->cpart( part ).hp();
385 if( hp / 20 > bash ) {
386 // Threshold damage thing means we just can't bash this down
387 layer.state[index] = ASL_CLOSED;
388 continue;
389 } else if( hp / 10 > bash ) {
390 // Threshold damage thing means we will fail to deal damage pretty often
391 hp *= 2;
392 }
393
394 newg += 2 * hp / bash + 8 + 4;
395 } else if( part >= 0 ) {
396 if( !doors || !veh->part_flag( part, VPFLAG_OPENABLE ) ) {
397 // Won't be openable, don't try from other sides
398 layer.state[index] = ASL_CLOSED;
399 }
400
401 continue;
402 }
403 } else if( rating > 1 ) {
404 // Expected number of turns to bash it down, 1 turn to move there
405 // and 5 turns of penalty not to trash everything just because we can
406 newg += ( 20 / rating ) + 2 + 10;
407 } else if( rating == 1 ) {
408 // Desperate measures, avoid whenever possible
409 newg += 500;
410 } else {
411 // Unbashable and unopenable from here
412 if( !doors || !terrain.open || !furniture.open ) {
413 // Or anywhere else for that matter
414 layer.state[index] = ASL_CLOSED;
415 }
416
417 continue;
418 }
419 }
420
421 if( trapavoid && p_special & PF_TRAP ) {
422 const auto &ter_trp = terrain.trap.obj();
423 const auto &trp = ter_trp.is_benign() ? tile.get_trap_t() : ter_trp;
424 if( !trp.is_benign() ) {
425 // For now make them detect all traps
426 if( has_zlevels() && terrain.has_flag( TFLAG_NO_FLOOR ) ) {
427 // Special case - ledge in z-levels
428 // Warning: really expensive, needs a cache
429 if( valid_move( p, tripoint( p.xy(), p.z - 1 ), false, true ) ) {
430 tripoint below( p.xy(), p.z - 1 );
431 if( !has_flag( TFLAG_NO_FLOOR, below ) ) {
432 // Otherwise this would have been a huge fall
433 auto &layer = pf.get_layer( p.z - 1 );
434 // From cur, not p, because we won't be walking on air
435 pf.add_point( layer.gscore[parent_index] + 10,
436 layer.score[parent_index] + 10 + 2 * rl_dist( below, t ),
437 cur, below );
438 }
439
440 // Close p, because we won't be walking on it
441 layer.state[index] = ASL_CLOSED;
442 continue;
443 }
444 } else if( trapavoid ) {
445 // Otherwise it's walkable
446 newg += 500;
447 }
448 }
449 }
450
451 if( sharpavoid && p_special & PF_SHARP ) {
452 layer.state[index] = ASL_CLOSED; // Avoid sharp things
453 }
454
455 }
456
457 // If not visited, add as open
458 // If visited, add it only if we can do so with better score
459 if( layer.state[index] == ASL_NONE || newg < layer.gscore[index] ) {
460 pf.add_point( newg, newg + 2 * rl_dist( p, t ), cur, p );
461 }
462 }
463
464 if( !has_zlevels() || !( cur_special & PF_UPDOWN ) || !settings.allow_climb_stairs ) {
465 // The part below is only for z-level pathing
466 continue;
467 }
468
469 const maptile &parent_tile = maptile_at_internal( cur );
470 const auto &parent_terrain = parent_tile.get_ter_t();
471 if( settings.allow_climb_stairs && cur.z > minz && parent_terrain.has_flag( TFLAG_GOES_DOWN ) ) {
472 tripoint dest( cur.xy(), cur.z - 1 );
473 if( vertical_move_destination<TFLAG_GOES_UP>( *this, dest ) ) {
474 auto &layer = pf.get_layer( dest.z );
475 pf.add_point( layer.gscore[parent_index] + 2,
476 layer.score[parent_index] + 2 * rl_dist( dest, t ),
477 cur, dest );
478 }
479 }
480 if( settings.allow_climb_stairs && cur.z < maxz && parent_terrain.has_flag( TFLAG_GOES_UP ) ) {
481 tripoint dest( cur.xy(), cur.z + 1 );
482 if( vertical_move_destination<TFLAG_GOES_DOWN>( *this, dest ) ) {
483 auto &layer = pf.get_layer( dest.z );
484 pf.add_point( layer.gscore[parent_index] + 2,
485 layer.score[parent_index] + 2 * rl_dist( dest, t ),
486 cur, dest );
487 }
488 }
489 if( cur.z < maxz && parent_terrain.has_flag( TFLAG_RAMP ) &&
490 valid_move( cur, tripoint( cur.xy(), cur.z + 1 ), false, true ) ) {
491 auto &layer = pf.get_layer( cur.z + 1 );
492 for( size_t it = 0; it < 8; it++ ) {
493 const tripoint above( cur.x + x_offset[it], cur.y + y_offset[it], cur.z + 1 );
494 pf.add_point( layer.gscore[parent_index] + 4,
495 layer.score[parent_index] + 4 + 2 * rl_dist( above, t ),
496 cur, above );
497 }
498 }
499 if( cur.z < maxz && parent_terrain.has_flag( TFLAG_RAMP_UP ) &&
500 valid_move( cur, tripoint( cur.xy(), cur.z + 1 ), false, true, true ) ) {
501 auto &layer = pf.get_layer( cur.z + 1 );
502 for( size_t it = 0; it < 8; it++ ) {
503 const tripoint above( cur.x + x_offset[it], cur.y + y_offset[it], cur.z + 1 );
504 pf.add_point( layer.gscore[parent_index] + 4,
505 layer.score[parent_index] + 4 + 2 * rl_dist( above, t ),
506 cur, above );
507 }
508 }
509 if( cur.z > minz && parent_terrain.has_flag( TFLAG_RAMP_DOWN ) &&
510 valid_move( cur, tripoint( cur.xy(), cur.z - 1 ), false, true, true ) ) {
511 auto &layer = pf.get_layer( cur.z - 1 );
512 for( size_t it = 0; it < 8; it++ ) {
513 const tripoint below( cur.x + x_offset[it], cur.y + y_offset[it], cur.z - 1 );
514 pf.add_point( layer.gscore[parent_index] + 4,
515 layer.score[parent_index] + 4 + 2 * rl_dist( below, t ),
516 cur, below );
517 }
518 }
519
520 } while( !done && !pf.empty() );
521
522 if( done ) {
523 ret.reserve( rl_dist( f, t ) * 2 );
524 tripoint cur = t;
525 // Just to limit max distance, in case something weird happens
526 for( int fdist = max_length; fdist != 0; fdist-- ) {
527 const int cur_index = flat_index( cur );
528 const auto &layer = pf.get_layer( cur.z );
529 const tripoint &par = layer.parent[cur_index];
530 if( cur == f ) {
531 break;
532 }
533
534 ret.push_back( cur );
535 // Jumps are acceptable on 1 z-level changes
536 // This is because stairs teleport the player too
537 if( rl_dist( cur, par ) > 1 && std::abs( cur.z - par.z ) != 1 ) {
538 debugmsg( "Jump in our route! %d:%d:%d->%d:%d:%d",
539 cur.x, cur.y, cur.z, par.x, par.y, par.z );
540 return ret;
541 }
542
543 cur = par;
544 }
545
546 std::reverse( ret.begin(), ret.end() );
547 }
548
549 return ret;
550}
bool has_zlevels() const
Definition: map.h:1684
const pathfinding_cache & get_pathfinding_cache_ref(int zlev) const
Definition: map.cpp:8807
point tripoint_to_mount(const tripoint &p) const
Definition: vehicle.cpp:3130
const vehicle_part & cpart(int part_num) const
Definition: vehicle.cpp:7085
bool part_flag(int p, const std::string &f) const
Definition: vehicle.cpp:2911
bool allowed_move(const point &from, const point &to) const
Definition: vehicle.cpp:3220
@ TFLAG_GOES_DOWN
Definition: mapdata.h:308
@ TFLAG_GOES_UP
Definition: mapdata.h:309
Definition: gates.h:28
Definition: overmap.h:50
bool is_disjoint(const Set1 &set1, const Set2 &set2)
constexpr int flat_index(const tripoint &p)
Definition: pathfinding.cpp:34
@ ASL_CLOSED
Definition: pathfinding.cpp:30
@ ASL_NONE
Definition: pathfinding.cpp:28
@ PF_VEHICLE
Definition: pathfinding.h:11
@ PF_WALL
Definition: pathfinding.h:10
@ PF_CLIMBABLE
Definition: pathfinding.h:15
@ PF_UPDOWN
Definition: pathfinding.h:14
@ PF_TRAP
Definition: pathfinding.h:13
@ PF_SHARP
Definition: pathfinding.h:16
@ PF_SLOW
Definition: pathfinding.h:9
const trap & get_trap_t() const
Definition: submap.h:293
@ VPFLAG_OPENABLE
Definition: veh_type.h:44

References pathfinding_settings::allow_climb_stairs, pathfinding_settings::allow_open_doors, vehicle::allowed_move(), ASL_CLOSED, ASL_NONE, pathfinding_settings::avoid_rough_terrain, pathfinding_settings::avoid_sharp, pathfinding_settings::avoid_traps, bash(), bash_rating_internal(), pathfinding_settings::bash_strength, pathfinding_settings::climb_cost, clip_to_bounds(), vehicle::cpart(), debugmsg, detail::digits::done, flat_index(), furniture, maptile::get_furn_t(), get_pathfinding_cache_ref(), maptile::get_ter_t(), maptile::get_trap_t(), has_flag(), has_zlevels(), vehicle_part::hp(), inbounds(), is_disjoint(), is_outside(), line_to(), maptile_at_internal(), pathfinding_settings::max_dist, pathfinding_settings::max_length, move_cost_internal(), vpart_position::obstacle_at_part(), vehicle::part_flag(), PF_CLIMBABLE, PF_SHARP, PF_SLOW, PF_TRAP, PF_UPDOWN, PF_VEHICLE, PF_WALL, cata::hash64_detail::ret, rl_dist(), route(), terrain, TFLAG_GOES_DOWN, TFLAG_GOES_UP, TFLAG_NO_FLOOR, TFLAG_RAMP, TFLAG_RAMP_DOWN, TFLAG_RAMP_UP, vehicle::tripoint_to_mount(), valid_move(), veh_at_internal(), VPFLAG_OPENABLE, tripoint::x, tripoint::xy(), tripoint::y, and tripoint::z.

Referenced by activity_on_turn_move_loot(), add_item_or_charges(), Character::can_mount(), npc::go_to_omt_destination(), game::handle_action(), game::list_items(), game::look_around(), perform_zone_activity_turn(), route(), route_adjacent(), activity_handlers::travel_do_turn(), game::try_get_left_click_action(), and npc::update_path().

◆ save()

void map::save ( )

Add currently loaded submaps (in grid) to the mapbuffer.

They will than be stored by that class and can be loaded from that class. This can be called several times, the mapbuffer takes care of adding the same submap several times. It should only be called after the map has been loaded. Submaps that have been loaded from the mapbuffer (and not generated) are already stored in the mapbuffer. TODO: determine if this is really needed? Submaps are already in the mapbuffer if they have been loaded from disc and the are added by map::generate, too. So when do they not appear in the mapbuffer?

Definition at line 6607 of file map.cpp.

6608{
6609 for( int gridx = 0; gridx < my_MAPSIZE; gridx++ ) {
6610 for( int gridy = 0; gridy < my_MAPSIZE; gridy++ ) {
6611 if( zlevels ) {
6612 for( int gridz = -OVERMAP_DEPTH; gridz <= OVERMAP_HEIGHT; gridz++ ) {
6613 saven( tripoint( gridx, gridy, gridz ) );
6614 }
6615 } else {
6616 saven( tripoint( gridx, gridy, abs_sub.z ) );
6617 }
6618 }
6619 }
6620}

References abs_sub, my_MAPSIZE, OVERMAP_DEPTH, OVERMAP_HEIGHT, saven(), tripoint::z, and zlevels.

Referenced by start_location::add_map_extra(), add_monsters(), start_location::burn(), talk_function::buy_100_logs(), talk_function::buy_10_logs(), create_lab_consoles(), construct::done_digormine_stair(), construct::done_mine_upstair(), farm_action(), talk_function::field_build_1(), talk_function::field_build_2(), talk_function::field_harvest(), talk_function::field_plant(), defense_game::init_map(), mission_start::kill_horde_master(), talk_function::loot_building(), om_cutdown_trees(), om_harvest_furn(), om_harvest_itm(), om_harvest_ter(), om_set_hide_site(), mission_start::place_deposit_box(), mission_start::place_dog(), mission_start::place_npc_software(), mission_start::place_priest_diary(), basecamp::place_results(), game::place_vehicle_nearby(), mission_start::place_zombie_mom(), start_location::prepare_map(), mission_start::ranch_nurse_1(), mission_start::ranch_nurse_2(), mission_start::ranch_nurse_3(), mission_start::ranch_nurse_4(), mission_start::ranch_nurse_5(), mission_start::ranch_nurse_6(), mission_start::ranch_nurse_7(), mission_start::ranch_nurse_8(), mission_start::ranch_nurse_9(), mission_start::ranch_scavenger_1(), mission_start::ranch_scavenger_2(), mission_start::ranch_scavenger_3(), mission_start::reveal_lab_train_depot(), game::save_maps(), and debug_menu::spawn_nested_mapgen().

◆ saven()

void map::saven ( const tripoint grid)
protected

Definition at line 6950 of file map.cpp.

6951{
6952 dbg( DL::Debug ) << "map::saven( world=" << abs_sub << ", grid=" << grid << " )";
6953 const int gridn = get_nonant( grid );
6954 submap *submap_to_save = getsubmap( gridn );
6955 if( submap_to_save == nullptr || submap_to_save->get_ter( point_zero ) == t_null ) {
6956 // This is a serious error and should be signaled as soon as possible
6957 debugmsg( "map::saven grid (%s) %s!", grid.to_string(),
6958 submap_to_save == nullptr ? "null" : "uninitialized" );
6959 return;
6960 }
6961
6962 const tripoint abs = abs_sub.xy() + grid;
6963
6964 if( !zlevels && grid.z != abs_sub.z ) {
6965 debugmsg( "Tried to save submap (%d,%d,%d) as (%d,%d,%d), which isn't supported in non-z-level builds",
6966 abs.x, abs.y, abs_sub.z, abs.x, abs.y, grid.z );
6967 }
6968
6969 dbg( DL::Debug ) << "map::saven abs: " << abs << " gridn: " << gridn;
6970
6971 // An edge case: restock_fruits relies on last_touched, so we must call it before save
6972 if( season_of_year( calendar::turn ) != season_of_year( submap_to_save->last_touched ) ) {
6973 const time_duration time_since_last_actualize = calendar::turn - submap_to_save->last_touched;
6974 for( int x = 0; x < SEEX; x++ ) {
6975 for( int y = 0; y < SEEY; y++ ) {
6976 const tripoint pnt = sm_to_ms_copy( grid ) + point( x, y );
6977 restock_fruits( pnt, time_since_last_actualize );
6978 }
6979 }
6980 }
6981
6982 submap_to_save->last_touched = calendar::turn;
6983 MAPBUFFER.add_submap( abs, submap_to_save );
6984}
bool add_submap(const tripoint &p, std::unique_ptr< submap > &sm)
Add a new submap to the buffer.
Definition: mapbuffer.cpp:68
@ Debug
Debug information (default: disabled).

References abs_sub, mapbuffer::add_submap(), dbg, Debug, debugmsg, get_nonant(), submap::get_ter(), getsubmap(), grid, submap::last_touched, MAPBUFFER, point_zero, restock_fruits(), season_of_year(), SEEX, SEEY, sm_to_ms_copy(), t_null, calendar::turn, tripoint::xy(), tripoint::z, and zlevels.

Referenced by generate(), and save().

◆ scent_blockers()

void map::scent_blockers ( std::array< std::array< char, MAPSIZE_X >, MAPSIZE_Y > &  scent_transfer,
const point min,
const point max 
)

Build the map of scent-resistant tiles.

Should be way faster than if done in game.cpp using public map functions.

Definition at line 8557 of file map.cpp.

8559{
8560 auto reduce = TFLAG_REDUCE_SCENT;
8561 auto block = TFLAG_NO_SCENT;
8562 auto fill_values = [&]( const tripoint & gp, const submap * sm, const point & lp ) {
8563 // We need to generate the x/y coordinates, because we can't get them "for free"
8564 const point p = lp + sm_to_ms_copy( gp.xy() );
8565 if( sm->get_ter( lp ).obj().has_flag( block ) ) {
8566 scent_transfer[p.x][p.y] = 0;
8567 } else if( sm->get_ter( lp ).obj().has_flag( reduce ) ||
8568 sm->get_furn( lp ).obj().has_flag( reduce ) ) {
8569 scent_transfer[p.x][p.y] = 1;
8570 } else {
8571 scent_transfer[p.x][p.y] = 5;
8572 }
8573
8574 return ITER_CONTINUE;
8575 };
8576
8577 function_over( tripoint( min, abs_sub.z ), tripoint( max, abs_sub.z ), fill_values );
8578
8579 const inclusive_rectangle<point> local_bounds( min, max );
8580
8581 // Now vehicles
8582
8583 auto vehs = get_vehicles();
8584 for( auto &wrapped_veh : vehs ) {
8585 vehicle &veh = *( wrapped_veh.v );
8586 for( const vpart_reference &vp : veh.get_any_parts( VPFLAG_OBSTACLE ) ) {
8587 const tripoint part_pos = vp.pos();
8588 if( local_bounds.contains( part_pos.xy() ) && scent_transfer[part_pos.x][part_pos.y] == 5 ) {
8589 scent_transfer[part_pos.x][part_pos.y] = 1;
8590 }
8591 }
8592
8593 // Doors, but only the closed ones
8594 for( const vpart_reference &vp : veh.get_any_parts( VPFLAG_OPENABLE ) ) {
8595 if( vp.part().open ) {
8596 continue;
8597 }
8598
8599 const tripoint part_pos = vp.pos();
8600 if( local_bounds.contains( part_pos.xy() ) && scent_transfer[part_pos.x][part_pos.y] == 5 ) {
8601 scent_transfer[part_pos.x][part_pos.y] = 1;
8602 }
8603 }
8604 }
8605}
void function_over(const tripoint &start, const tripoint &end, Functor fun) const
Runs a functor over given submaps over submaps in the area, getting next submap only when the current...
Definition: map.cpp:8503
@ TFLAG_REDUCE_SCENT
Definition: mapdata.h:278
@ TFLAG_NO_SCENT
Definition: mapdata.h:284
@ VPFLAG_OBSTACLE
Definition: veh_type.h:42

References abs_sub, inclusive_rectangle< Point, >::contains(), function_over(), vehicle::get_any_parts(), get_vehicles(), ITER_CONTINUE, coords::sm, sm_to_ms_copy(), TFLAG_NO_SCENT, TFLAG_REDUCE_SCENT, VPFLAG_OBSTACLE, VPFLAG_OPENABLE, point::x, tripoint::x, tripoint::xy(), point::y, tripoint::y, and tripoint::z.

Referenced by scent_map::update().

◆ sees() [1/2]

bool map::sees ( const tripoint F,
const tripoint T,
int  range 
) const

Returns whether F sees T with a view range of range.

Definition at line 6142 of file map.cpp.

6143{
6144 int dummy = 0;
6145 return sees( F, T, range, dummy );
6146}

References sees().

Referenced by apply_ammo_effects(), find_clear_path(), mattack::flame(), explosion_handler::explosion_funcs::flashbang(), get_heat_radiation(), projectile_attack(), Creature::sees(), sees(), Character::sees_with_infrared(), shake_vehicle(), shoot(), spawn_monsters_submap_group(), and vehicle_selector::vehicle_selector().

◆ sees() [2/2]

bool map::sees ( const tripoint F,
const tripoint T,
int  range,
int &  bresenham_slope 
) const
private

Don't expose the slope adjust outside map functions.

This one is internal-only, we don't want to expose the slope tweaking ickiness outside the map class.

Parameters
FThing doing the seeing
TThing being seen
rangeVision range of F
bresenham_slopeIndicates the start offset of Bresenham line used to connect the two points, and may subsequently be used to form a path between them. Set to zero if the function returns false.

Definition at line 6151 of file map.cpp.

6153{
6154 if( ( range >= 0 && range < rl_dist( F, T ) ) ||
6155 !inbounds( T ) ) {
6156 bresenham_slope = 0;
6157 return false; // Out of range!
6158 }
6159 // Cannonicalize the order of the tripoints so the cache is reflexive.
6160 const tripoint &min = F < T ? F : T;
6161 const tripoint &max = !( F < T ) ? F : T;
6162 // A little gross, just pack the values into a point.
6163 const point key(
6164 min.x << 16 | min.y << 8 | ( min.z + OVERMAP_DEPTH ),
6165 max.x << 16 | max.y << 8 | ( max.z + OVERMAP_DEPTH )
6166 );
6167 char cached = skew_vision_cache.get( key, -1 );
6168 if( cached >= 0 ) {
6169 return cached > 0;
6170 }
6171
6172 bool visible = true;
6173
6174 // Ugly `if` for now
6175 if( !fov_3d || F.z == T.z ) {
6176
6177 point last_point = F.xy();
6178 bresenham( F.xy(), T.xy(), bresenham_slope,
6179 [this, &visible, &T, &last_point]( const point & new_point ) {
6180 // Exit before checking the last square, it's still visible even if opaque.
6181 if( new_point.x == T.x && new_point.y == T.y ) {
6182 return false;
6183 }
6184 if( !this->is_transparent( tripoint( new_point, T.z ) ) ||
6185 obscured_by_vehicle_rotation( tripoint( last_point, T.z ), tripoint( new_point, T.z ) ) ) {
6186 visible = false;
6187 return false;
6188 }
6189 last_point = new_point;
6190 return true;
6191 } );
6192 skew_vision_cache.insert( 100000, key, visible ? 1 : 0 );
6193 return visible;
6194 }
6195
6196 tripoint last_point = F;
6197 bresenham( F, T, bresenham_slope, 0,
6198 [this, &visible, &T, &last_point]( const tripoint & new_point ) {
6199 // Exit before checking the last square if it's not a vertical transition,
6200 // it's still visible even if opaque.
6201 if( new_point == T && last_point.z == T.z ) {
6202 return false;
6203 }
6204
6205 // TODO: Allow transparent floors (and cache them!)
6206 if( new_point.z == last_point.z ) {
6207 if( !this->is_transparent( new_point ) || obscured_by_vehicle_rotation( last_point, new_point ) ) {
6208 visible = false;
6209 return false;
6210 }
6211 } else {
6212 const int max_z = std::max( new_point.z, last_point.z );
6213 if( ( has_floor_or_support( {new_point.xy(), max_z} ) ||
6214 !is_transparent( {new_point.xy(), last_point.z} ) ) &&
6215 ( has_floor_or_support( {last_point.xy(), max_z} ) ||
6216 !is_transparent( {last_point.xy(), new_point.z} ) ) ) {
6217 visible = false;
6218 return false;
6219 }
6220 }
6221
6222 last_point = new_point;
6223 return true;
6224 } );
6225 skew_vision_cache.insert( 100000, key, visible ? 1 : 0 );
6226 return visible;
6227}

References bresenham(), fov_3d, inbounds(), obscured_by_vehicle_rotation(), OVERMAP_DEPTH, rl_dist(), skew_vision_cache, tripoint::x, tripoint::xy(), tripoint::y, and tripoint::z.

◆ sees_some_items() [1/2]

bool map::sees_some_items ( const tripoint p,
const Creature who 
) const

Check if creature can see some items at p.

Includes:

  • check for items at this location (has_items(p))
  • check for SEALED flag (sealed furniture/terrain makes items not visible under any circumstances).
  • check for CONTAINER flag (makes items only visible when the creature is at p or at an adjacent square).

Definition at line 4736 of file map.cpp.

4737{
4738 // Can only see items if there are any items.
4739 return has_items( p ) && could_see_items( p, who.pos() );
4740}

References could_see_items(), has_items(), and Creature::pos().

Referenced by game::butcher(), editmap::draw_main_ui_overlay(), draw_maptile(), npc::find_corpse_to_pulp(), npc::find_item(), game::find_nearby_items(), vehicle::interact_with(), game::print_items_info(), and npc::see_item_say_smth().

◆ sees_some_items() [2/2]

bool map::sees_some_items ( const tripoint p,
const tripoint from 
) const

Definition at line 4742 of file map.cpp.

4743{
4744 return has_items( p ) && could_see_items( p, from );
4745}

References could_see_items(), and has_items().

◆ set() [1/2]

void map::set ( const point p,
const ter_id new_terrain,
const furn_id new_furniture 
)
inline

Definition at line 834 of file map.h.

834 {
835 furn_set( p, new_furniture );
836 ter_set( p, new_terrain );
837 }

References furn_set(), and ter_set().

◆ set() [2/2]

void map::set ( const tripoint p,
const ter_id new_terrain,
const furn_id new_furniture 
)

Definition at line 1319 of file map.cpp.

1320{
1321 furn_set( p, new_furniture );
1322 ter_set( p, new_terrain );
1323}

References furn_set(), and ter_set().

Referenced by farm_action(), talk_function::field_plant(), mapgen_function_json_base::formatted_set_incredibly_simple(), and activity_handlers::plant_seed_finish().

◆ set_abs_sub()

void map::set_abs_sub ( const tripoint p)
protected

Sets abs_sub, see there.

Uses the same coordinate system as abs_sub.

Definition at line 8283 of file map.cpp.

8284{
8285 abs_sub = p;
8286}

References abs_sub.

Referenced by fake_map::fake_map(), generate(), load(), shift(), and vertical_shift().

◆ set_field_age()

time_duration map::set_field_age ( const tripoint p,
const field_type_id type,
const time_duration age,
bool  isoffset = false 
)

Set age of field entry at point.

Parameters
pLocation of field
typeID of field
ageNew age of specified field
isoffsetIf true, the given age value is added to the existing value, if false, the existing age is ignored and overridden.
Returns
resulting age or -1_turns if not present (does not create a new field).

Definition at line 5339 of file map.cpp.

5341{
5342 if( field_entry *const field_ptr = get_field( p, type ) ) {
5343 return field_ptr->set_field_age( ( isoffset ? field_ptr->get_field_age() : 0_turns ) + age );
5344 }
5345 return -1_turns;
5346}

References get_field(), and type.

Referenced by game::grabbed_furn_move(), mod_field_age(), and game::walk_move().

◆ set_field_intensity()

int map::set_field_intensity ( const tripoint p,
const field_type_id type,
int  new_intensity,
bool  isoffset = false 
)

Set intensity of field entry at point, creating if not present, removing if intensity becomes 0.

Parameters
pLocation of field
typeID of field
new_intensityNew intensity of field
isoffsetIf true, the given new_intensity value is added to the existing value, if false, the existing intensity is ignored and overridden.
Returns
resulting intensity, or 0 for not present (either removed or not created at all).

Definition at line 5352 of file map.cpp.

5355{
5356 field_entry *field_ptr = get_field( p, type );
5357 if( field_ptr != nullptr ) {
5358 int adj = ( isoffset ? field_ptr->get_field_intensity() : 0 ) + new_intensity;
5359 if( adj > 0 ) {
5360 field_ptr->set_field_intensity( adj );
5361 return adj;
5362 } else {
5363 remove_field( p, type );
5364 return 0;
5365 }
5366 } else if( 0 + new_intensity > 0 ) {
5367 return add_field( p, type, new_intensity ) ? new_intensity : 0;
5368 }
5369
5370 return 0;
5371}

References add_field(), get_field(), field_entry::get_field_intensity(), remove_field(), field_entry::set_field_intensity(), and type.

Referenced by editmap::edit_fld(), game::grabbed_furn_move(), mod_field_intensity(), spell_move(), and game::walk_move().

◆ set_floor_cache_dirty()

void map::set_floor_cache_dirty ( const int  zlev)
inline

◆ set_graffiti()

void map::set_graffiti ( const tripoint p,
const std::string &  contents 
)

Definition at line 7815 of file map.cpp.

7816{
7817 if( !inbounds( p ) ) {
7818 return;
7819 }
7820 point l;
7821 submap *const current_submap = get_submap_at( p, l );
7822 current_submap->set_graffiti( l, contents );
7823}
void set_graffiti(const point &p, const std::string &new_graffiti)
Definition: submap.cpp:97

References get_submap_at(), inbounds(), and submap::set_graffiti().

Referenced by jmapgen_graffiti::apply().

◆ set_memory_seen_cache_dirty()

void map::set_memory_seen_cache_dirty ( const tripoint p)
inline

Definition at line 463 of file map.h.

463 {
464 const int offset = p.x + p.y * MAPSIZE_Y;
465 if( offset >= 0 && offset < MAPSIZE_X * MAPSIZE_Y ) {
466 get_cache( p.z ).map_memory_seen_cache.reset( offset );
467 }
468 }

References get_cache(), level_cache::map_memory_seen_cache, MAPSIZE_X, MAPSIZE_Y, tripoint::x, tripoint::y, and tripoint::z.

Referenced by furn_set(), vehicle::stop(), and ter_set().

◆ set_outside_cache_dirty()

void map::set_outside_cache_dirty ( const int  zlev)
inline

Definition at line 442 of file map.h.

442 {
443 if( inbounds_z( zlev ) ) {
444 get_cache( zlev ).outside_cache_dirty = true;
445 }
446 }

References get_cache(), inbounds_z(), and level_cache::outside_cache_dirty.

Referenced by draw_fill_background(), furn_set(), loadn(), editmap::mapgen_preview(), on_vehicle_moved(), ter_set(), and game::vertical_shift().

◆ set_pathfinding_cache_dirty()

void map::set_pathfinding_cache_dirty ( int  zlev)

◆ set_radiation() [1/2]

void map::set_radiation ( const point p,
const int  value 
)
inline

Definition at line 1214 of file map.h.

1214 {
1215 set_radiation( tripoint( p, abs_sub.z ), value );
1216 }

References abs_sub, set_radiation(), and tripoint::z.

◆ set_radiation() [2/2]

void map::set_radiation ( const tripoint p,
int  value 
)

Definition at line 4046 of file map.cpp.

4047{
4048 if( !inbounds( p ) ) {
4049 return;
4050 }
4051
4052 point l;
4053 submap *const current_submap = get_submap_at( p, l );
4054
4055 current_submap->set_radiation( l, value );
4056}

References get_submap_at(), inbounds(), and submap::set_radiation().

Referenced by jmapgen_setmap::apply(), create_anomaly(), draw_lab(), mapgen_crater(), mapgen_null(), mapgen_test(), and set_radiation().

◆ set_seen_cache_dirty() [1/2]

void map::set_seen_cache_dirty ( const int  zlevel)
inline

Definition at line 435 of file map.h.

435 {
436 if( inbounds_z( zlevel ) ) {
437 level_cache &cache = get_cache( zlevel );
438 cache.seen_cache_dirty = true;
439 }
440 }

References get_cache(), inbounds_z(), and level_cache::seen_cache_dirty.

◆ set_seen_cache_dirty() [2/2]

void map::set_seen_cache_dirty ( const tripoint  change_location)
inline

Definition at line 421 of file map.h.

421 {
422 if( inbounds( change_location ) ) {
423 level_cache &cache = get_cache( change_location.z );
424 if( cache.seen_cache_dirty ) {
425 return;
426 }
427 if( cache.seen_cache[change_location.x][change_location.y] != 0.0 ||
428 cache.camera_cache[change_location.x][change_location.y] != 0.0 ) {
429 cache.seen_cache_dirty = true;
430 }
431 }
432 }

References level_cache::camera_cache, get_cache(), inbounds(), level_cache::seen_cache, level_cache::seen_cache_dirty, tripoint::x, tripoint::y, and tripoint::z.

Referenced by add_field(), draw_fill_background(), furn_set(), loadn(), trapfunc::map_regen(), vehicle::merge_rackable_vehicle(), vehicle::open_or_close(), process_fields_in_submap(), remove_field(), avatar::set_movement_mode(), DefaultRemovePartHandler::set_transparency_cache_dirty(), vehicle::split_vehicles(), ter_set(), and weather_manager::update_weather().

◆ set_signage()

void map::set_signage ( const tripoint p,
const std::string &  message 
) const

Definition at line 4011 of file map.cpp.

4012{
4013 if( !inbounds( p ) ) {
4014 return;
4015 }
4016
4017 point l;
4018 submap *const current_submap = get_submap_at( p, l );
4019
4020 current_submap->set_signage( l, message );
4021}
void set_signage(const point &p, const std::string &s)
Definition: submap.cpp:137
std::string message
Definition: mapgen.cpp:408

References get_submap_at(), inbounds(), mapgen_defer::message, and submap::set_signage().

Referenced by jmapgen_sign::apply(), MapExtras::mx_grave(), MapExtras::mx_minefield(), and iexamine::sign().

◆ set_suspension_cache_dirty()

void map::set_suspension_cache_dirty ( const int  zlev)
inline

Definition at line 454 of file map.h.

454 {
455 if( inbounds_z( zlev ) ) {
456 get_cache( zlev ).suspension_cache_dirty = true;
457 }
458 }

References get_cache(), inbounds_z(), and level_cache::suspension_cache_dirty.

Referenced by loadn(), editmap::mapgen_preview(), and ter_set().

◆ set_temperature() [1/2]

void map::set_temperature ( const point p,
int  new_temperature 
)
inline

Definition at line 1231 of file map.h.

1231 {
1232 set_temperature( tripoint( p, abs_sub.z ), new_temperature );
1233 }

References abs_sub, set_temperature(), and tripoint::z.

◆ set_temperature() [2/2]

void map::set_temperature ( const tripoint p,
int  temperature 
)

Definition at line 4080 of file map.cpp.

4081{
4082 if( !inbounds( p ) ) {
4083 return;
4084 }
4085
4086 get_submap_at( p )->set_temperature( new_temperature );
4087}
void set_temperature(int new_temperature)
Definition: submap.h:198

References get_submap_at(), inbounds(), and submap::set_temperature().

Referenced by draw_lab(), and set_temperature().

◆ set_transparency_cache_dirty() [1/2]

void map::set_transparency_cache_dirty ( const int  zlev)
inline

◆ set_transparency_cache_dirty() [2/2]

void map::set_transparency_cache_dirty ( const tripoint p)
inline

Definition at line 414 of file map.h.

414 {
415 if( inbounds( p ) ) {
416 const tripoint smp = ms_to_sm_copy( p );
417 get_cache( smp.z ).transparency_cache_dirty.set( smp.x * MAPSIZE + smp.y );
418 }
419 }

References get_cache(), inbounds(), MAPSIZE, ms_to_sm_copy(), level_cache::transparency_cache_dirty, tripoint::x, tripoint::y, and tripoint::z.

◆ setsubmap()

void map::setsubmap ( size_t  grididx,
submap smap 
)
protected

Set the submap pointer in grid at the give index.

This is the inverse of getsubmap, any existing pointer is overwritten. The index must be valid. The given submap pointer must not be null.

Definition at line 8302 of file map.cpp.

8303{
8304 if( grididx >= grid.size() ) {
8305 debugmsg( "Tried to access invalid grid index %d", grididx );
8306 return;
8307 } else if( smap == nullptr ) {
8308 debugmsg( "Tried to set NULL submap pointer at index %d", grididx );
8309 return;
8310 }
8311 grid[grididx] = smap;
8312}

References debugmsg, and grid.

Referenced by copy_grid(), fake_map::fake_map(), generate(), and loadn().

◆ shake_vehicle()

units::angle map::shake_vehicle ( vehicle veh,
int  velocity_before,
units::angle  direction 
)
Strength reduces chance of being thrown from your seat when not wearing a seatbelt Strength reduces chance of being thrown from your seat when not wearing a seatbelt Dexterity reduces chance of losing control of vehicle when shaken Driving reduces chance of losing control of vehicle when shaken Strength reduces distance thrown from seat in a vehicle impact

Definition at line 1631 of file vehicle_move.cpp.

1633{
1634 const int d_vel = std::abs( veh.velocity - velocity_before ) / 100;
1635
1636 std::vector<rider_data> riders = veh.get_riders();
1637
1638 units::angle coll_turn = 0_degrees;
1639 for( const rider_data &r : riders ) {
1640 const int ps = r.prt;
1641 Creature *rider = r.psg;
1642 if( rider == nullptr ) {
1643 debugmsg( "throw passenger: empty passenger at part %d", ps );
1644 continue;
1645 }
1646
1647 const tripoint part_pos = veh.global_part_pos3( ps );
1648 if( rider->pos() != part_pos ) {
1649 debugmsg( "throw passenger: passenger at %d,%d,%d, part at %d,%d,%d",
1650 rider->posx(), rider->posy(), rider->posz(),
1651 part_pos.x, part_pos.y, part_pos.z );
1653 continue;
1654 }
1655
1656 player *psg = dynamic_cast<player *>( rider );
1657 monster *pet = dynamic_cast<monster *>( rider );
1658
1659 bool throw_from_seat = false;
1660 int move_resist = 1;
1661 if( psg ) {
1662 ///\EFFECT_STR reduces chance of being thrown from your seat when not wearing a seatbelt
1663 move_resist = psg->str_cur * 150 + 500;
1664 } else {
1665 int pet_resist = 0;
1666 if( pet != nullptr ) {
1667 pet_resist = static_cast<int>( to_kilogram( pet->get_weight() ) * 200 );
1668 }
1669 move_resist = std::max( 100, pet_resist );
1670 }
1671 if( veh.part_with_feature( ps, VPFLAG_SEATBELT, true ) == -1 ) {
1672 ///\EFFECT_STR reduces chance of being thrown from your seat when not wearing a seatbelt
1673 throw_from_seat = d_vel * rng( 80, 120 ) > move_resist;
1674 }
1675
1676 // Damage passengers if d_vel is too high
1677 if( !throw_from_seat && ( 10 * d_vel ) > 6 * rng( 50, 100 ) ) {
1678 const int dmg = d_vel * rng( 70, 100 ) / 400;
1679 if( psg ) {
1680 psg->hurtall( dmg, nullptr );
1682 _( "You take %d damage by the power of the impact!" ),
1683 _( "<npcname> takes %d damage by the power of the "
1684 "impact!" ), dmg );
1685 } else {
1686 pet->apply_damage( nullptr, bodypart_id( "torso" ), dmg );
1687 }
1688 }
1689
1690 if( psg && veh.player_in_control( *psg ) ) {
1691 const int lose_ctrl_roll = rng( 0, d_vel );
1692 ///\EFFECT_DEX reduces chance of losing control of vehicle when shaken
1693
1694 ///\EFFECT_DRIVING reduces chance of losing control of vehicle when shaken
1695 if( lose_ctrl_roll > psg->dex_cur * 2 + psg->get_skill_level( skill_driving ) * 3 ) {
1697 _( "You lose control of the %s." ),
1698 _( "<npcname> loses control of the %s." ), veh.name );
1699 int turn_amount = rng( 1, 3 ) * std::sqrt( std::abs( veh.velocity ) ) / 30;
1700 if( turn_amount < 1 ) {
1701 turn_amount = 1;
1702 }
1703 units::angle turn_angle = std::min( turn_amount * 15_degrees, 120_degrees );
1704 coll_turn = one_in( 2 ) ? turn_angle : -turn_angle;
1705 }
1706 }
1707
1708 if( throw_from_seat ) {
1709 if( psg ) {
1711 _( "You are hurled from the %s's seat by "
1712 "the power of the impact!" ),
1713 _( "<npcname> is hurled from the %s's seat by "
1714 "the power of the impact!" ), veh.name );
1715 unboard_vehicle( part_pos );
1716 } else if( get_player_character().sees( part_pos ) ) {
1717 add_msg( m_bad, _( "The %s is hurled from %s's by the power of the impact!" ),
1718 pet->disp_name(), veh.name );
1719 }
1720 ///\EFFECT_STR reduces distance thrown from seat in a vehicle impact
1721 g->fling_creature( rider, direction + rng_float( -30_degrees, 30_degrees ),
1722 std::max( 10, d_vel - move_resist / 100 ) );
1723 }
1724 }
1725
1726 return coll_turn;
1727}
int dex_cur
Definition: character.h:248
int get_skill_level(const skill_id &ident) const
Definition: character.cpp:3356
units::mass get_weight() const override
Definition: monster.cpp:2697
std::string disp_name(bool possessive=false, bool capitalize_first=false) const override
Definition: monster.cpp:537
@ VPFLAG_SEATBELT
Definition: veh_type.h:45
static const skill_id skill_driving("driving")

References _, add_msg(), player::add_msg_player_or_npc(), monster::apply_damage(), debugmsg, Character::dex_cur, monster::disp_name(), g, get_player_character(), vehicle::get_riders(), Character::get_skill_level(), monster::get_weight(), vehicle::global_part_pos3(), Character::hurtall(), m_bad, m_warning, vehicle::name, one_in(), vehicle::part(), vehicle::part_with_feature(), vehicle_part::passenger_flag, vehicle::player_in_control(), Creature::pos(), Creature::posx(), Creature::posy(), Creature::posz(), vehicle_part::remove_flag(), rng(), rng_float(), sees(), skill_driving, Character::str_cur, units::to_kilogram(), unboard_vehicle(), vehicle::velocity, VPFLAG_SEATBELT, tripoint::x, tripoint::y, and tripoint::z.

Referenced by move_vehicle().

◆ shift()

void map::shift ( const point s)

Shift the map along the vector s.

This is like loading the map with coordinates derived from the current position of the map (abs_sub) plus the shift vector. Note: the map must have been loaded before this can be called.

Definition at line 6779 of file map.cpp.

6780{
6781 // Special case of 0-shift; refresh the map
6782 if( sp == point_zero ) {
6783 return; // Skip this?
6784 }
6785
6786 if( std::abs( sp.x ) > 1 || std::abs( sp.y ) > 1 ) {
6787 debugmsg( "map::shift called with a shift of more than one submap" );
6788 }
6789
6790 const tripoint abs = get_abs_sub();
6791
6792 set_abs_sub( abs + sp );
6793
6794 // if player is in vehicle, (s)he must be shifted with vehicle too
6795 if( g->u.in_vehicle ) {
6796 g->u.setx( g->u.posx() - sp.x * SEEX );
6797 g->u.sety( g->u.posy() - sp.y * SEEY );
6798 }
6799
6800 g->shift_destination_preview( point( -sp.x * SEEX, -sp.y * SEEY ) );
6801
6802 shift_traps( tripoint( sp, 0 ) );
6803
6804 vehicle *remoteveh = g->remoteveh();
6805
6806 const int zmin = zlevels ? -OVERMAP_DEPTH : abs.z;
6807 const int zmax = zlevels ? OVERMAP_HEIGHT : abs.z;
6808 for( int gridz = zmin; gridz <= zmax; gridz++ ) {
6809 for( vehicle *veh : get_cache( gridz ).vehicle_list ) {
6810 veh->zones_dirty = true;
6811 }
6812 }
6813
6814 constexpr half_open_rectangle<point> boundaries_2d( point_zero, point( MAPSIZE_Y, MAPSIZE_X ) );
6815 const point shift_offset_pt( -sp.x * SEEX, -sp.y * SEEY );
6816
6817 // Clear vehicle list and rebuild after shift
6819 // Shift the map sx submaps to the right and sy submaps down.
6820 // sx and sy should never be bigger than +/-1.
6821 // absx and absy are our position in the world, for saving/loading purposes.
6822 for( int gridz = zmin; gridz <= zmax; gridz++ ) {
6823 clear_vehicle_list( gridz );
6824 shift_bitset_cache<MAPSIZE_X, SEEX>( get_cache( gridz ).map_memory_seen_cache, sp );
6825 shift_bitset_cache<MAPSIZE, 1>( get_cache( gridz ).field_cache, sp );
6826 if( sp.x >= 0 ) {
6827 for( int gridx = 0; gridx < my_MAPSIZE; gridx++ ) {
6828 if( sp.y >= 0 ) {
6829 for( int gridy = 0; gridy < my_MAPSIZE; gridy++ ) {
6830 if( ( sp.x > 0 && gridx == 0 ) || ( sp.y > 0 && gridy == 0 ) ) {
6831 submaps_with_active_items.erase( { abs.x + gridx, abs.y + gridy, gridz } );
6832 }
6833 if( gridx + sp.x < my_MAPSIZE && gridy + sp.y < my_MAPSIZE ) {
6834 copy_grid( tripoint( gridx, gridy, gridz ),
6835 tripoint( gridx + sp.x, gridy + sp.y, gridz ) );
6836 update_vehicle_list( get_submap_at_grid( {gridx, gridy, gridz} ), gridz );
6837 } else {
6838 loadn( tripoint( gridx, gridy, gridz ), true );
6839 }
6840 }
6841 } else { // sy < 0; work through it backwards
6842 for( int gridy = my_MAPSIZE - 1; gridy >= 0; gridy-- ) {
6843 if( ( sp.x > 0 && gridx == 0 ) || gridy == my_MAPSIZE - 1 ) {
6844 submaps_with_active_items.erase( { abs.x + gridx, abs.y + gridy, gridz } );
6845 }
6846 if( gridx + sp.x < my_MAPSIZE && gridy + sp.y >= 0 ) {
6847 copy_grid( tripoint( gridx, gridy, gridz ),
6848 tripoint( gridx + sp.x, gridy + sp.y, gridz ) );
6849 update_vehicle_list( get_submap_at_grid( { gridx, gridy, gridz } ), gridz );
6850 } else {
6851 loadn( tripoint( gridx, gridy, gridz ), true );
6852 }
6853 }
6854 }
6855 }
6856 } else { // sx < 0; work through it backwards
6857 for( int gridx = my_MAPSIZE - 1; gridx >= 0; gridx-- ) {
6858 if( sp.y >= 0 ) {
6859 for( int gridy = 0; gridy < my_MAPSIZE; gridy++ ) {
6860 if( gridx == my_MAPSIZE - 1 || ( sp.y > 0 && gridy == 0 ) ) {
6861 submaps_with_active_items.erase( { abs.x + gridx, abs.y + gridy, gridz } );
6862 }
6863 if( gridx + sp.x >= 0 && gridy + sp.y < my_MAPSIZE ) {
6864 copy_grid( tripoint( gridx, gridy, gridz ),
6865 tripoint( gridx + sp.x, gridy + sp.y, gridz ) );
6866 update_vehicle_list( get_submap_at_grid( { gridx, gridy, gridz } ), gridz );
6867 } else {
6868 loadn( tripoint( gridx, gridy, gridz ), true );
6869 }
6870 }
6871 } else { // sy < 0; work through it backwards
6872 for( int gridy = my_MAPSIZE - 1; gridy >= 0; gridy-- ) {
6873 if( gridx == my_MAPSIZE - 1 || gridy == my_MAPSIZE - 1 ) {
6874 submaps_with_active_items.erase( { abs.x + gridx, abs.y + gridy, gridz } );
6875 }
6876 if( gridx + sp.x >= 0 && gridy + sp.y >= 0 ) {
6877 copy_grid( tripoint( gridx, gridy, gridz ),
6878 tripoint( gridx + sp.x, gridy + sp.y, gridz ) );
6879 update_vehicle_list( get_submap_at_grid( { gridx, gridy, gridz } ), gridz );
6880 } else {
6881 loadn( tripoint( gridx, gridy, gridz ), true );
6882 }
6883 }
6884 }
6885 }
6886 }
6887 }
6888 if( zlevels ) {
6889 //Go through the generated maps and fill in the roofs
6890 for( int gridz = zmin; gridz <= zmax; gridz++ ) {
6891 if( sp.x > 0 ) {
6892 for( int gridy = 0; gridy < my_MAPSIZE; gridy++ ) {
6893 add_roofs( {my_MAPSIZE - 1, gridy, gridz} );
6894 }
6895 } else if( sp.x < 0 ) {
6896 for( int gridy = 0; gridy < my_MAPSIZE; gridy++ ) {
6897 add_roofs( {0, gridy, gridz} );
6898 }
6899 }
6900
6901 if( sp.y > 0 ) {
6902 for( int gridx = 0; gridx < my_MAPSIZE; gridx++ ) {
6903 add_roofs( {gridx, my_MAPSIZE - 1, gridz} );
6904 }
6905 } else if( sp.y < 0 ) {
6906 for( int gridx = 0; gridx < my_MAPSIZE; gridx++ ) {
6907 add_roofs( {gridx, 0, gridz} );
6908 }
6909 }
6910 }
6911 }
6912
6914
6915 g->setremoteveh( remoteveh );
6916
6917 if( !support_cache_dirty.empty() ) {
6918 shift_tripoint_set( support_cache_dirty, shift_offset_pt, boundaries_2d );
6919 }
6920}
void copy_grid(const tripoint &to, const tripoint &from)
Definition: map.cpp:7520
void shift_traps(const tripoint &shift)
As part of the map shifting, this shifts the trap locations stored in traplocs.
Definition: map.cpp:6647
template void shift_bitset_cache< MAPSIZE_X, SEEX >(std::bitset< MAPSIZE_X *MAPSIZE_X > &cache, const point &s)
static void shift_tripoint_set(std::set< tripoint > &set, const point &offset, const half_open_rectangle< point > &boundaries)
Definition: map.cpp:6706
template void shift_bitset_cache< MAPSIZE, 1 >(std::bitset< MAPSIZE *MAPSIZE > &cache, const point &s)
int remoteveh(player *, item *, bool, const tripoint &)
Definition: iuse.cpp:8255

References add_roofs(), clear_vehicle_cache(), clear_vehicle_list(), copy_grid(), debugmsg, g, get_abs_sub(), get_cache(), get_submap_at_grid(), loadn(), MAPSIZE_X, MAPSIZE_Y, my_MAPSIZE, OVERMAP_DEPTH, OVERMAP_HEIGHT, point_zero, iuse::remoteveh(), reset_vehicle_cache(), SEEX, SEEY, set_abs_sub(), shift_bitset_cache< MAPSIZE, 1 >(), shift_bitset_cache< MAPSIZE_X, SEEX >(), shift_traps(), shift_tripoint_set(), submaps_with_active_items, support_cache_dirty, update_vehicle_list(), point::x, point::y, and zlevels.

Referenced by shift_traps(), and game::update_map().

◆ shift_traps()

void map::shift_traps ( const tripoint shift)
protected

As part of the map shifting, this shifts the trap locations stored in traplocs.

Parameters
shiftThe amount shifting in submap, the same as go into shift.

Definition at line 6647 of file map.cpp.

6648{
6649 // Offset needs to have sign opposite to shift direction
6650 const tripoint offset( -shift.x * SEEX, -shift.y * SEEY, -shift.z );
6651 for( auto iter = field_furn_locs.begin(); iter != field_furn_locs.end(); ) {
6652 tripoint &pos = *iter;
6653 pos += offset;
6654 if( inbounds( pos ) ) {
6655 ++iter;
6656 } else {
6657 iter = field_furn_locs.erase( iter );
6658 }
6659 }
6660 for( auto &traps : traplocs ) {
6661 for( auto iter = traps.begin(); iter != traps.end(); ) {
6662 tripoint &pos = *iter;
6663 pos += offset;
6664 if( inbounds( pos ) ) {
6665 ++iter;
6666 } else {
6667 // Theoretical enhancement: if this is not the last entry of the vector,
6668 // move the last entry into pos and remove the last entry instead of iter.
6669 // This would avoid moving all the remaining entries.
6670 iter = traps.erase( iter );
6671 }
6672 }
6673 }
6674}
void shift(const point &s)
Shift the map along the vector s.
Definition: map.cpp:6779

References field_furn_locs, inbounds(), SEEX, SEEY, shift(), and traplocs.

Referenced by shift().

◆ shift_vehicle_z()

void map::shift_vehicle_z ( vehicle veh,
int  z_shift 
)

Definition at line 6733 of file map.cpp.

6734{
6735
6736 tripoint src = veh.global_pos3();
6737 tripoint dst = src + tripoint_above * z_shift;
6738
6739 submap *src_submap = get_submap_at( src );
6740 submap *dst_submap = get_submap_at( dst );
6741
6742 int our_i = -1;
6743 for( size_t i = 0; i < src_submap->vehicles.size(); i++ ) {
6744 if( src_submap->vehicles[i].get() == &veh ) {
6745 our_i = i;
6746 break;
6747 }
6748 }
6749
6750 if( our_i == -1 ) {
6751 debugmsg( "shift_vehicle [%s] failed could not find vehicle", veh.name );
6752 return;
6753 }
6754
6755 for( auto &prt : veh.get_all_parts() ) {
6756 prt.part().precalc[0].z -= z_shift;
6757 }
6758
6759 veh.set_submap_moved( tripoint( dst.x / SEEX, dst.y / SEEY, dst.z ) );
6760 auto src_submap_veh_it = src_submap->vehicles.begin() + our_i;
6761 dst_submap->vehicles.push_back( std::move( *src_submap_veh_it ) );
6762 src_submap->vehicles.erase( src_submap_veh_it );
6763 dst_submap->is_uniform = false;
6765
6766 update_vehicle_list( dst_submap, dst.z );
6767
6768 level_cache &ch = get_cache( src.z );
6769 for( const vehicle *elem : ch.vehicle_list ) {
6770 if( elem == &veh ) {
6771 ch.vehicle_list.erase( &veh );
6772 ch.zone_vehicles.erase( &veh );
6773 break;
6774 }
6775 }
6776
6777}

References debugmsg, vehicle::get_all_parts(), get_cache(), get_submap_at(), vehicle::global_pos3(), invalidate_max_populated_zlev(), submap::is_uniform, avatar_action::move(), vehicle::name, SEEX, SEEY, vehicle::set_submap_moved(), tripoint_above, update_vehicle_list(), level_cache::vehicle_list, submap::vehicles, tripoint::x, tripoint::y, tripoint::z, and level_cache::zone_vehicles.

Referenced by vehicle::shift_zlevel().

◆ shoot()

void map::shoot ( const tripoint p,
projectile proj,
bool  hit_items 
)

Definition at line 3725 of file map.cpp.

3726{
3727 float initial_damage = 0.0;
3728 for( const damage_unit &dam : proj.impact ) {
3729 initial_damage += dam.amount * dam.damage_multiplier;
3730 initial_damage += dam.res_pen;
3731 }
3732 if( initial_damage < 0 ) {
3733 return;
3734 }
3735
3736 float dam = initial_damage;
3737
3738 if( has_flag( "ALARMED", p ) && !g->timed_events.queued( TIMED_EVENT_WANTED ) ) {
3739 sounds::sound( p, 30, sounds::sound_t::alarm, _( "an alarm sound!" ), true, "environment",
3740 "alarm" );
3741 const tripoint abs = ms_to_sm_copy( getabs( p ) );
3742 g->timed_events.add( TIMED_EVENT_WANTED, calendar::turn + 30_minutes, 0, abs );
3743 }
3744
3745 const bool inc = proj.has_effect( ammo_effect_INCENDIARY ) ||
3746 proj.impact.type_damage( DT_HEAT ) > 0;
3747 if( const optional_vpart_position vp = veh_at( p ) ) {
3748 dam = vp->vehicle().damage( vp->part_index(), dam, inc ? DT_HEAT : DT_STAB, hit_items );
3749 }
3750
3751 ter_id terrain = ter( p );
3752 ter_t ter = terrain.obj();
3753
3754 if( ter.bash.ranged ) {
3755 const ranged_bash_info &ri = *ter.bash.ranged;
3756 if( !hit_items && !check( ri.block_unaimed_chance ) ) {
3757 // Nothing, it's a miss
3758 } else if( ri.reduction_laser && proj.has_effect( ammo_effect_LASER ) ) {
3759 dam -= rng( ri.reduction_laser->min, ri.reduction_laser->max );
3760 } else {
3761 dam -= rng( ri.reduction.min, ri.reduction.max );
3762 if( dam > ri.destroy_threshold ) {
3763 bash_params params{0, false, true, hit_items, 1.0, false};
3764 bash_ter_success( p, params );
3765 }
3766 if( dam <= 0 && is_transparent( p ) && get_avatar().sees( p ) ) {
3767 add_msg( _( "The shot is stopped by the %s!" ), tername( p ) );
3768 }
3769 if( ri.flammable && inc ) {
3770 add_field( p, fd_fire, 1 );
3771 }
3772 }
3773 } else if( impassable( p ) && !is_transparent( p ) ) {
3774 bash( p, dam, false );
3775 // TODO: Preserve some residual damage when it makes sense.
3776 dam = 0;
3777 }
3778
3779 for( const ammo_effect_str_id &ae_id : proj.get_ammo_effects() ) {
3780 const ammo_effect &ae = *ae_id;
3781 if( ae.trail_field_type ) {
3782 if( x_in_y( ae.trail_chance, 100 ) ) {
3784 }
3785 }
3786 }
3787
3788 dam = std::max( 0.0f, dam );
3789
3790 // Check fields?
3791 const field_entry *fieldhit = get_field( p, fd_web );
3792 if( fieldhit != nullptr ) {
3793 if( inc ) {
3794 add_field( p, fd_fire, fieldhit->get_field_intensity() - 1 );
3795 } else if( dam > 5 + fieldhit->get_field_intensity() * 5 &&
3796 one_in( 5 - fieldhit->get_field_intensity() ) ) {
3797 dam -= rng( 1, 2 + fieldhit->get_field_intensity() * 2 );
3798 remove_field( p, fd_web );
3799 }
3800 }
3801
3802 // Rescale the damage
3803 if( dam <= 0 ) {
3804 proj.impact.damage_units.clear();
3805 return;
3806 } else if( dam < initial_damage ) {
3807 proj.impact.mult_damage( dam / static_cast<double>( initial_damage ) );
3808 }
3809
3810 //Projectiles with NO_ITEM_DAMAGE flag won't damage items at all
3811 if( !hit_items || !inbounds( p ) ) {
3812 return;
3813 }
3814
3815 // Make sure the message is sensible for the ammo effects. Lasers aren't projectiles.
3816 std::string damage_message;
3817 if( proj.has_effect( ammo_effect_LASER ) ) {
3818 damage_message = _( "laser beam" );
3819 } else if( proj.has_effect( ammo_effect_LIGHTNING ) ) {
3820 damage_message = _( "bolt of electricity" );
3821 } else if( proj.has_effect( ammo_effect_PLASMA ) ) {
3822 damage_message = _( "bolt of plasma" );
3823 } else {
3824 damage_message = _( "flying projectile" );
3825 }
3826
3827 smash_items( p, dam, damage_message, false );
3828}
avatar & get_avatar()
Definition: avatar.cpp:103
@ DT_STAB
Definition: damage.h:27
static const ammo_effect_str_id ammo_effect_LIGHTNING("LIGHTNING")
static const ammo_effect_str_id ammo_effect_LASER("LASER")
static const ammo_effect_str_id ammo_effect_INCENDIARY("INCENDIARY")
static const ammo_effect_str_id ammo_effect_PLASMA("PLASMA")
int check(unformattable)
Definition: fmtlib_core.h:1610
int trail_chance
Definition: ammo_effect.h:45
int trail_intensity_max
Definition: ammo_effect.h:44
int trail_intensity_min
Definition: ammo_effect.h:43
field_type_id trail_field_type
Definition: ammo_effect.h:40
std::vector< damage_unit > damage_units
Definition: damage.h:52
float type_damage(damage_type dt) const
Definition: damage.cpp:64
void mult_damage(double multiplier, bool pre_armor=false)
Definition: damage.cpp:48
float amount
Definition: damage.h:37
float damage_multiplier
Definition: damage.h:40
float res_pen
Definition: damage.h:38
const std::set< ammo_effect_str_id > & get_ammo_effects()
Definition: projectile.h:42
damage_instance impact
Definition: projectile.h:21
bool has_effect(const ammo_effect_str_id &id) const
Definition: projectile.h:55
bool flammable
Definition: mapdata.h:40
numeric_interval< int > reduction
Definition: mapdata.h:36
cata::optional< numeric_interval< int > > reduction_laser
Definition: mapdata.h:38
int destroy_threshold
Definition: mapdata.h:39
units::probability block_unaimed_chance
Definition: mapdata.h:41

References _, add_field(), add_msg(), sounds::alarm, ammo_effect_INCENDIARY, ammo_effect_LASER, ammo_effect_LIGHTNING, ammo_effect_PLASMA, damage_unit::amount, bash(), bash_ter_success(), ranged_bash_info::block_unaimed_chance, detail::check(), damage_unit::damage_multiplier, damage_instance::damage_units, ranged_bash_info::destroy_threshold, DT_HEAT, DT_STAB, fd_fire, fd_web, ranged_bash_info::flammable, g, projectile::get_ammo_effects(), get_avatar(), get_field(), field_entry::get_field_intensity(), getabs(), projectile::has_effect(), has_flag(), projectile::impact, impassable(), inbounds(), is_transparent(), ms_to_sm_copy(), damage_instance::mult_damage(), one_in(), ranged_bash_info::reduction, ranged_bash_info::reduction_laser, remove_field(), damage_unit::res_pen, rng(), sees(), smash_items(), sounds::sound(), ter(), tername(), terrain, TIMED_EVENT_WANTED, ammo_effect::trail_chance, ammo_effect::trail_field_type, ammo_effect::trail_intensity_max, ammo_effect::trail_intensity_min, calendar::turn, damage_instance::type_damage(), veh_at(), and x_in_y().

Referenced by ranged::execute_shaped_attack(), and projectile_attack().

◆ smash_items()

void map::smash_items ( const tripoint p,
int  power,
const std::string &  cause_message,
bool  do_destroy 
)

Tries to smash the items at the given tripoint.

Definition at line 2994 of file map.cpp.

2996{
2997 if( !has_items( p ) ) {
2998 return;
2999 }
3000
3001 // Keep track of how many items have been damaged, and what the first one is
3002 int items_damaged = 0;
3003 int items_destroyed = 0;
3004 std::string damaged_item_name;
3005
3006 // TODO: Bullets should be pretty much corpse-only
3007 constexpr const int min_destroy_threshold = 50;
3008
3009 std::vector<item> contents;
3010 map_stack items = i_at( p );
3011 for( auto i = items.begin(); i != items.end(); ) {
3012 // If the power is low or it's not an explosion, only pulp rezing corpses
3013 if( ( power < min_destroy_threshold || !do_destroy ) && !i->can_revive() ) {
3014 i++;
3015 continue;
3016 }
3017
3018 // Active explosives arbitrarily get double the destroy threshold
3019 bool is_active_explosive = i->active && i->type->get_use( "explosion" ) != nullptr;
3020 if( is_active_explosive && i->charges == 0 ) {
3021 i++;
3022 continue;
3023 }
3024
3025 const float material_factor = i->chip_resistance( true );
3026 // Intact non-rezing get a boost
3027 const float intact_mult = 2.0f -
3028 ( static_cast<float>( i->damage_level( i->max_damage() ) ) / i->max_damage() );
3029 const float destroy_threshold = min_destroy_threshold
3030 + material_factor * intact_mult
3031 + ( is_active_explosive ? min_destroy_threshold : 0 );
3032 // For pulping, only consider material resistance. Non-rezing can only be destroyed.
3033 const float pulp_threshold = i->can_revive() ? material_factor : destroy_threshold;
3034 // Active explosives that will explode this turn are indestructible (they are exploding "now")
3035 if( power < pulp_threshold ) {
3036 i++;
3037 continue;
3038 }
3039
3040 bool item_was_destroyed = false;
3041 float destroy_chance = ( power - pulp_threshold ) / 4.0;
3042
3043 const bool by_charges = i->count_by_charges();
3044 if( by_charges ) {
3045 destroy_chance *= i->charges_per_volume( 250_ml );
3046 if( x_in_y( destroy_chance, destroy_threshold ) ) {
3047 item_was_destroyed = true;
3048 }
3049 } else {
3050 const field_type_id type_blood = i->is_corpse() ? i->get_mtype()->bloodType() : fd_null;
3051 float roll = rng_float( 0.0, destroy_chance );
3052 if( roll >= destroy_threshold ) {
3053 item_was_destroyed = true;
3054 } else if( roll >= pulp_threshold ) {
3055 // Only pulp
3056 i->set_damage( i->max_damage() );
3057 // TODO: Blood streak cone away from explosion
3058 add_splash( type_blood, p, 1, destroy_chance );
3059 // If it was the first item to be damaged, note it
3060 if( items_damaged == 0 ) {
3061 damaged_item_name = i->tname();
3062 }
3063 items_damaged++;
3064 }
3065 }
3066
3067 // Remove them if they were damaged too much
3068 if( item_was_destroyed ) {
3069 // But save the contents, except for irremovable gunmods
3070 for( item *elem : i->contents.all_items_top() ) {
3071 if( !elem->is_irremovable() ) {
3072 contents.push_back( item( *elem ) );
3073 }
3074 }
3075
3076 if( items_damaged == 0 ) {
3077 damaged_item_name = i->tname();
3078 }
3079 i = i_rem( p, i );
3080 items_damaged++;
3081 items_destroyed++;
3082 } else {
3083 i++;
3084 }
3085 }
3086
3087 // Let the player know that the item was damaged if they can see it.
3088 if( items_destroyed > 1 && g->u.sees( p ) ) {
3089 add_msg( m_bad, _( "The %s destroys several items!" ), cause_message );
3090 } else if( items_destroyed == 1 && items_damaged == 1 && g->u.sees( p ) ) {
3091 //~ %1$s: the cause of destruction, %2$s: destroyed item name
3092 add_msg( m_bad, _( "The %1$s destroys the %2$s!" ), cause_message, damaged_item_name );
3093 } else if( items_damaged > 1 && g->u.sees( p ) ) {
3094 add_msg( m_bad, _( "The %s damages several items." ), cause_message );
3095 } else if( items_damaged == 1 && g->u.sees( p ) ) {
3096 //~ %1$s: the cause of damage, %2$s: damaged item name
3097 add_msg( m_bad, _( "The %1$s damages the %2$s." ), cause_message, damaged_item_name );
3098 }
3099
3100 for( const item &it : contents ) {
3101 add_item_or_charges( p, it );
3102 }
3103}
void add_splash(const field_type_id &type, const tripoint &center, int radius, int intensity)
Definition: map.cpp:5540

References _, add_item_or_charges(), add_msg(), add_splash(), item_contents::all_items_top(), item_stack::begin(), item::contents, item_stack::end(), fd_null, g, has_items(), i_at(), i_rem(), m_bad, rng_float(), and x_in_y().

Referenced by explosion_handler::do_blast(), explosion_handler::do_blast_new(), move_vehicle(), and shoot().

◆ spawn_an_item() [1/2]

void map::spawn_an_item ( const point p,
item  new_item,
int  charges,
int  damlevel 
)
inline

Definition at line 1310 of file map.h.

1310 {
1311 spawn_an_item( tripoint( p, abs_sub.z ), new_item, charges, damlevel );
1312 }
item & spawn_an_item(const tripoint &p, item new_item, int charges, int damlevel)
Definition: map.cpp:4145

References abs_sub, spawn_an_item(), and tripoint::z.

◆ spawn_an_item() [2/2]

item & map::spawn_an_item ( const tripoint p,
item  new_item,
int  charges,
int  damlevel 
)

Definition at line 4145 of file map.cpp.

4147{
4148 if( charges && new_item.charges > 0 ) {
4149 //let's fail silently if we specify charges for an item that doesn't support it
4150 new_item.charges = charges;
4151 }
4152 new_item = new_item.in_its_container();
4153 if( ( new_item.made_of( LIQUID ) && has_flag( "SWIMMABLE", p ) ) ||
4154 has_flag( "DESTROY_ITEM", p ) ) {
4155 return null_item_reference();
4156 }
4157
4158 new_item.set_damage( damlevel );
4159
4160 return add_item_or_charges( p, new_item );
4161}
item & set_damage(int qty)
Filter setting damage constrained by min_damage and max_damage.
Definition: item.cpp:714
item in_its_container() const
Returns this item into its default container.
Definition: item.cpp:841

References add_item_or_charges(), item::charges, has_flag(), item::in_its_container(), LIQUID, item::made_of(), null_item_reference(), and item::set_damage().

Referenced by salvage_actor::cut_up(), spawn_an_item(), and spawn_item().

◆ spawn_artifact()

void map::spawn_artifact ( const tripoint p)

Definition at line 4184 of file map.cpp.

4185{
4187}
itype_id new_artifact()
Definition: artifact.cpp:677

References add_item_or_charges(), new_artifact(), and calendar::start_of_cataclysm.

Referenced by draw_mine(), and draw_temple().

◆ spawn_item() [1/4]

void map::spawn_item ( const point p,
const itype_id type_id,
unsigned  quantity = 1,
int  charges = 0,
const time_point birthday = calendar::start_of_cataclysm,
int  damlevel = 0 
)
inline

Definition at line 1263 of file map.h.

1265 {
1266 spawn_item( tripoint( p, abs_sub.z ), type_id, quantity, charges, birthday, damlevel );
1267 }

References abs_sub, spawn_item(), and tripoint::z.

◆ spawn_item() [2/4]

void map::spawn_item ( const point p,
const std::string &  type_id,
unsigned  quantity = 1,
int  charges = 0,
const time_point birthday = calendar::start_of_cataclysm,
int  damlevel = 0 
)
inline

Definition at line 1276 of file map.h.

1278 {
1279 spawn_item( tripoint( p, abs_sub.z ), type_id, quantity, charges, birthday, damlevel );
1280 }

References abs_sub, spawn_item(), and tripoint::z.

◆ spawn_item() [3/4]

void map::spawn_item ( const tripoint p,
const itype_id type_id,
unsigned  quantity = 1,
int  charges = 0,
const time_point birthday = calendar::start_of_cataclysm,
int  damlevel = 0 
)

Definition at line 4194 of file map.cpp.

4197{
4198 if( type_id.is_null() ) {
4199 return;
4200 }
4201
4202 if( item_is_blacklisted( type_id ) ) {
4203 return;
4204 }
4205 // recurse to spawn (quantity - 1) items
4206 for( size_t i = 1; i < quantity; i++ ) {
4207 spawn_item( p, type_id, 1, charges, birthday, damlevel );
4208 }
4209 // spawn the item
4210 item new_item( type_id, birthday );
4211 if( one_in( 3 ) && new_item.has_flag( "VARSIZE" ) ) {
4212 new_item.set_flag( "FIT" );
4213 }
4214
4215 spawn_an_item( p, new_item, charges, damlevel );
4216}
bool is_null() const
Returns whether this represents the id of the null-object (in which case it's the null-id).
Definition: string_id.h:317
bool item_is_blacklisted(const itype_id &id)

References item::has_flag(), string_id< T >::is_null(), item_is_blacklisted(), one_in(), item::set_flag(), spawn_an_item(), and spawn_item().

Referenced by computer_session::action_extract_rad_source(), jmapgen_spawn_item::apply(), MapExtras::burned_ground_parser(), talk_function::buy_100_logs(), talk_function::buy_10_logs(), activity_handlers::chop_planks_finish(), create_anomaly(), create_burnproducts(), iexamine::curtains(), monexamine::deactivate_pet(), MapExtras::dead_vegetation_parser(), game::disable_robot(), construct::done_window_curtains(), draw_lab(), draw_office_tower(), explosion_handler::emp_blast(), iexamine::fertilize_plant(), dig_activity_actor::finish(), iexamine::flower_marloss(), activity_handlers::hacksaw_finish(), vehicle::handle_trap(), make_rubble(), mapgen_cavern(), mapgen_tutorial(), MapExtras::mx_casings(), MapExtras::mx_drugdeal(), MapExtras::mx_grave(), MapExtras::mx_mayhem(), MapExtras::mx_minefield(), MapExtras::mx_roadworks(), om_cutdown_trees(), trap::on_disarmed(), activity_handlers::oxytorch_finish(), pick_plant(), mission_start::place_deposit_box(), MapExtras::place_fumarole(), mission_start::place_priest_diary(), place_vending(), activity_handlers::pry_nails_finish(), mission_start::ranch_nurse_1(), mission_start::ranch_nurse_2(), mission_start::ranch_scavenger_1(), mission_start::ranch_scavenger_2(), mission_start::ranch_scavenger_3(), iexamine::recycle_compactor(), iexamine::shrub_marloss(), sinkhole_safety_roll(), spawn_item(), Character::suffer_from_other_mutations(), iexamine::tree_hickory(), iexamine::tree_marloss(), try_remove_bear_trap(), try_remove_heavysnare(), try_remove_lightsnare(), unroll_digging(), and game::vertical_move().

◆ spawn_item() [4/4]

void map::spawn_item ( const tripoint p,
const std::string &  type_id,
unsigned  quantity = 1,
int  charges = 0,
const time_point birthday = calendar::start_of_cataclysm,
int  damlevel = 0 
)
inline

Definition at line 1271 of file map.h.

1273 {
1274 spawn_item( p, itype_id( type_id ), quantity, charges, birthday, damlevel );
1275 }

References itype_id, and spawn_item().

◆ spawn_items() [1/2]

void map::spawn_items ( const point p,
const std::vector< item > &  new_items 
)
inline

Definition at line 1386 of file map.h.

1386 {
1387 spawn_items( tripoint( p, abs_sub.z ), new_items );
1388 }

References abs_sub, spawn_items(), and tripoint::z.

◆ spawn_items() [2/2]

std::vector< item * > map::spawn_items ( const tripoint p,
const std::vector< item > &  new_items 
)

Definition at line 4163 of file map.cpp.

4164{
4165 std::vector<item *> ret;
4166 if( !inbounds( p ) || has_flag( "DESTROY_ITEM", p ) ) {
4167 return ret;
4168 }
4169 const bool swimmable = has_flag( "SWIMMABLE", p );
4170 for( const item &new_item : new_items ) {
4171
4172 if( new_item.made_of( LIQUID ) && swimmable ) {
4173 continue;
4174 }
4175 item &it = add_item_or_charges( p, new_item );
4176 if( !it.is_null() ) {
4177 ret.push_back( &it );
4178 }
4179 }
4180
4181 return ret;
4182}
bool is_null() const
Definition: item.cpp:732

References add_item_or_charges(), has_flag(), inbounds(), item::is_null(), LIQUID, and cata::hash64_detail::ret.

Referenced by jmapgen_loot::apply(), bash_furn_success(), bash_items(), bash_ter_success(), complete_construction(), construct::done_deconstruct(), dig_activity_actor::finish(), dig_channel_activity_actor::finish(), talk_function::loot_building(), MapExtras::mx_casings(), MapExtras::mx_corpses(), process_fields_in_submap(), put_items_from_loc(), veh_utils::repair_part(), smash(), and spawn_items().

◆ spawn_monsters()

void map::spawn_monsters ( bool  ignore_sight)

Spawn monsters from submap spawn points and from the overmap.

Parameters
ignore_sightIf true, monsters may spawn in the view of the player character (useful when the whole map has been loaded instead, e.g. when starting a new game, or after teleportation or after moving vertically). If false, monsters are not spawned in view of player character.

Definition at line 7718 of file map.cpp.

7719{
7720 const int zmin = zlevels ? -OVERMAP_DEPTH : abs_sub.z;
7721 const int zmax = zlevels ? OVERMAP_HEIGHT : abs_sub.z;
7722 tripoint gp;
7723 int &gx = gp.x;
7724 int &gy = gp.y;
7725 int &gz = gp.z;
7726 for( gz = zmin; gz <= zmax; gz++ ) {
7727 for( gx = 0; gx < my_MAPSIZE; gx++ ) {
7728 for( gy = 0; gy < my_MAPSIZE; gy++ ) {
7729 spawn_monsters_submap( gp, ignore_sight );
7730 }
7731 }
7732 }
7733}
void spawn_monsters_submap(const tripoint &gp, bool ignore_sight)
Definition: map.cpp:7663

References abs_sub, my_MAPSIZE, OVERMAP_DEPTH, OVERMAP_HEIGHT, spawn_monsters_submap(), tripoint::x, tripoint::y, tripoint::z, and zlevels.

Referenced by game::do_turn(), editmap::mapgen_preview(), game::place_player_overmap(), game::start_game(), game::update_map(), and game::vertical_shift().

◆ spawn_monsters_submap()

void map::spawn_monsters_submap ( const tripoint gp,
bool  ignore_sight 
)
private

Definition at line 7663 of file map.cpp.

7664{
7665 // Load unloaded monsters
7666 // TODO: fix point types
7668
7669 // Only spawn new monsters after existing monsters are loaded.
7670 // TODO: fix point types
7671 auto groups = overmap_buffer.groups_at( tripoint_abs_sm( gp + abs_sub.xy() ) );
7672 for( auto &mgp : groups ) {
7673 spawn_monsters_submap_group( gp, *mgp, ignore_sight );
7674 }
7675
7676 submap *const current_submap = get_submap_at_grid( gp );
7677 const tripoint gp_ms = sm_to_ms_copy( gp );
7678
7679 for( auto &i : current_submap->spawns ) {
7680 const tripoint center = gp_ms + i.pos;
7682
7683 for( int j = 0; j < i.count; j++ ) {
7684 monster tmp( i.type );
7685 tmp.mission_id = i.mission_id;
7686 if( i.name != "NONE" ) {
7687 tmp.unique_name = i.name;
7688 }
7689 if( i.friendly ) {
7690 tmp.friendly = -1;
7691 }
7692
7693 const auto valid_location = [&]( const tripoint & p ) {
7694 // Checking for creatures via g is only meaningful if this is the main game map.
7695 // If it's some local map instance, the coordinates will most likely not even match.
7696 return ( !g || &get_map() != this || !g->critter_at( p ) ) && tmp.can_move_to( p );
7697 };
7698
7699 const auto place_it = [&]( const tripoint & p ) {
7700 monster *const placed = g->place_critter_at( make_shared_fast<monster>( tmp ), p );
7701 if( placed ) {
7702 placed->on_load();
7703 }
7704 };
7705
7706 // First check out defined spawn location for a valid placement, and if that doesn't work
7707 // then fall back to picking a random point that is a valid location.
7708 if( valid_location( center ) ) {
7709 place_it( center );
7710 } else if( const cata::optional<tripoint> pos = random_point( points, valid_location ) ) {
7711 place_it( *pos );
7712 }
7713 }
7714 }
7715 current_submap->spawns.clear();
7716}
void spawn_monsters_submap_group(const tripoint &gp, mongroup &group, bool ignore_sight)
Definition: map.cpp:7529
void on_load()
Retroactively update monster.
Definition: monster.cpp:3009
std::vector< mongroup * > groups_at(const tripoint_abs_sm &p)
Monster groups at p - absolute submap coordinates.
void spawn_monster(const tripoint_abs_sm &p)
Spawn monsters from the overmap onto the main map (game::m).

References abs_sub, monster::can_move_to(), center, monster::friendly, g, get_map(), get_submap_at_grid(), overmapbuffer::groups_at(), monster::mission_id, monster::on_load(), overmap_buffer, points_in_radius(), random_point(), sm_to_ms_copy(), overmapbuffer::spawn_monster(), spawn_monsters_submap_group(), submap::spawns, monster::unique_name, and tripoint::xy().

Referenced by spawn_monsters().

◆ spawn_monsters_submap_group()

void map::spawn_monsters_submap_group ( const tripoint gp,
mongroup group,
bool  ignore_sight 
)
private

Definition at line 7529 of file map.cpp.

7530{
7531 const int s_range = std::min( HALF_MAPSIZE_X,
7532 g->u.sight_range( g->light_level( g->u.posz() ) ) );
7533 int pop = group.population;
7534 std::vector<tripoint> locations;
7535 if( !ignore_sight ) {
7536 // If the submap is one of the outermost submaps, assume that monsters are
7537 // invisible there.
7538 if( gp.x == 0 || gp.y == 0 || gp.x + 1 == MAPSIZE || gp.y + 1 == MAPSIZE ) {
7539 ignore_sight = true;
7540 }
7541 }
7542
7543 if( gp.z != g->u.posz() ) {
7544 // Note: this is only OK because 3D vision isn't a thing yet
7545 ignore_sight = true;
7546 }
7547
7548 static const auto allow_on_terrain = [&]( const tripoint & p ) {
7549 // TODO: flying creatures should be allowed to spawn without a floor,
7550 // but the new creature is created *after* determining the terrain, so
7551 // we can't check for it here.
7552 return passable( p ) && has_floor( p );
7553 };
7554
7555 // If the submap is uniform, we can skip many checks
7556 const submap *current_submap = get_submap_at_grid( gp );
7557 bool ignore_terrain_checks = false;
7558 bool ignore_inside_checks = gp.z < 0;
7559 if( current_submap->is_uniform ) {
7560 const tripoint upper_left{ SEEX * gp.x, SEEY * gp.y, gp.z };
7561 if( !allow_on_terrain( upper_left ) ||
7562 ( !ignore_inside_checks && has_flag_ter_or_furn( TFLAG_INDOORS, upper_left ) ) ) {
7563 const tripoint glp = getabs( gp );
7564 dbg( DL::Warn ) << "Empty locations for group " << group.type.str()
7565 << " at uniform submap " << gp << " global " << glp;
7566 return;
7567 }
7568
7569 ignore_terrain_checks = true;
7570 ignore_inside_checks = true;
7571 }
7572
7573 for( int x = 0; x < SEEX; ++x ) {
7574 for( int y = 0; y < SEEY; ++y ) {
7575 int fx = x + SEEX * gp.x;
7576 int fy = y + SEEY * gp.y;
7577 tripoint fp{ fx, fy, gp.z };
7578 if( g->critter_at( fp ) != nullptr ) {
7579 continue; // there is already some creature
7580 }
7581
7582 if( !ignore_terrain_checks && !allow_on_terrain( fp ) ) {
7583 continue; // solid area, impassable
7584 }
7585
7586 if( !ignore_sight && sees( g->u.pos(), fp, s_range ) ) {
7587 continue; // monster must spawn outside the viewing range of the player
7588 }
7589
7590 if( !ignore_inside_checks && has_flag_ter_or_furn( TFLAG_INDOORS, fp ) ) {
7591 continue; // monster must spawn outside.
7592 }
7593
7594 locations.push_back( fp );
7595 }
7596 }
7597
7598 if( locations.empty() ) {
7599 // TODO: what now? there is no possible place to spawn monsters, most
7600 // likely because the player can see all the places.
7601 const tripoint glp = getabs( gp );
7602 dbg( DL::Warn ) << "Empty locations for group " << group.type.str()
7603 << " at " << gp << " global " << glp;
7604 // Just kill the group. It's not like we're removing existing monsters
7605 // Unless it's a horde - then don't kill it and let it spawn behind a tree or smoke cloud
7606 if( !group.horde ) {
7607 group.clear();
7608 }
7609
7610 return;
7611 }
7612
7613 if( pop ) {
7614 // Populate the group from its population variable.
7615 for( int m = 0; m < pop; m++ ) {
7617 if( !spawn_details.name ) {
7618 continue;
7619 }
7620 monster tmp( spawn_details.name );
7621
7622 // If a monster came from a horde population, configure them to always be willing to rejoin a horde.
7623 if( group.horde ) {
7624 tmp.set_horde_attraction( MHA_ALWAYS );
7625 }
7626 for( int i = 0; i < spawn_details.pack_size; i++ ) {
7627 group.monsters.push_back( tmp );
7628 }
7629 }
7630 }
7631
7632 // Find horde's target submap
7633 // TODO: fix point types
7634 tripoint horde_target( tripoint( -abs_sub.xy(), abs_sub.z ) + group.target.xy().raw() );
7635 sm_to_ms( horde_target );
7636 for( auto &tmp : group.monsters ) {
7637 for( int tries = 0; tries < 10 && !locations.empty(); tries++ ) {
7639 if( !tmp.can_move_to( p ) ) {
7640 continue; // target can not contain the monster
7641 }
7642 if( group.horde ) {
7643 // Give monster a random point near horde's expected destination
7644 const tripoint rand_dest = horde_target +
7645 point( rng( 0, SEEX ), rng( 0, SEEY ) );
7646 const int turns = rl_dist( p, rand_dest ) + group.interest;
7647 tmp.wander_to( rand_dest, turns );
7648 add_msg( m_debug, "%s targeting %d,%d,%d", tmp.disp_name(),
7649 tmp.wander_pos.x, tmp.wander_pos.y, tmp.wander_pos.z );
7650 }
7651
7652 monster *const placed = g->place_critter_at( make_shared_fast<monster>( tmp ), p );
7653 if( placed ) {
7654 placed->on_load();
7655 }
7656 break;
7657 }
7658 }
7659 // indicates the group is empty, and can be removed later
7660 group.clear();
7661}
void sm_to_ms(int &x, int &y)
static constexpr int HALF_MAPSIZE_X
@ MHA_ALWAYS
Definition: monster.h:76
generic_factory< overmap_location > locations("overmap location")

References abs_sub, add_msg(), dbg, g, get_submap_at_grid(), getabs(), MonsterGroupManager::GetResultFromGroup(), HALF_MAPSIZE_X, has_flag_ter_or_furn(), has_floor(), submap::is_uniform, anonymous_namespace{overmap_location.cpp}::locations, m_debug, MAPSIZE, MHA_ALWAYS, MonsterGroupResult::name, monster::on_load(), MonsterGroupResult::pack_size, passable(), random_entry_removed(), rl_dist(), rng(), sees(), SEEX, SEEY, monster::set_horde_attraction(), sm_to_ms(), TFLAG_INDOORS, Warn, tripoint::x, tripoint::xy(), tripoint::y, and tripoint::z.

Referenced by spawn_monsters_submap().

◆ spawn_natural_artifact()

void map::spawn_natural_artifact ( const tripoint p,
artifact_natural_property  prop 
)

Definition at line 4189 of file map.cpp.

4190{
4192}
itype_id new_natural_artifact(artifact_natural_property prop)
Definition: artifact.cpp:931

References add_item_or_charges(), new_natural_artifact(), and calendar::start_of_cataclysm.

Referenced by debug_menu::debug(), and MapExtras::mx_portal_in().

◆ spread_gas()

void map::spread_gas ( field_entry cur,
const tripoint p,
int  percent_spread,
const time_duration outdoor_age_speedup,
scent_block sblk 
)
private

Definition at line 251 of file map_field.cpp.

253{
254 map &here = get_map();
255 // TODO: fix point types
256 const oter_id &cur_om_ter =
258 const bool sheltered = g->is_sheltered( p );
260 const int winddirection = weather.winddirection;
261 const int windpower = get_local_windpower( weather.windspeed, cur_om_ter, p, winddirection,
262 sheltered );
263
264 const int current_intensity = cur.get_field_intensity();
265 const field_type_id ft_id = cur.get_field_type();
266
267 const int scent_neutralize = ft_id->get_intensity_level( current_intensity -
269
270 if( scent_neutralize > 0 ) {
271 // modify scents by neutralization value (minus)
272 for( const tripoint &tmp : points_in_radius( p, 1 ) ) {
273 sblk.apply_gas( tmp, scent_neutralize );
274 }
275 }
276
277 // Dissipate faster outdoors.
278 if( is_outside( p ) ) {
279 const time_duration current_age = cur.get_field_age();
280 cur.set_field_age( current_age + outdoor_age_speedup );
281 }
282
283 // Bail out if we don't meet the spread chance or required intensity.
284 if( current_intensity <= 1 || rng( 1, 100 - windpower ) > percent_spread ) {
285 return;
286 }
287
288 // First check if we can fall
289 // TODO: Make fall and rise chances parameters to enable heavy/light gas
290 if( zlevels && p.z > -OVERMAP_DEPTH ) {
291 const tripoint down{ p.xy(), p.z - 1 };
292 if( gas_can_spread_to( cur, p, down ) && valid_move( p, down, true, true ) ) {
293 maptile down_tile = maptile_at_internal( down );
294 gas_spread_to( cur, down_tile, down );
295 return;
296 }
297 }
298
299 auto neighs = get_neighbors( p );
300 size_t end_it = static_cast<size_t>( rng( 0, neighs.size() - 1 ) );
301 std::vector<size_t> spread;
302 std::vector<size_t> neighbour_vec;
303 // Then, spread to a nearby point.
304 // If not possible (or randomly), try to spread up
305 // Wind direction will block the field spreading into the wind.
306 // Start at end_it + 1, then wrap around until all elements have been processed.
307 for( size_t i = ( end_it + 1 ) % neighs.size(), count = 0;
308 count != neighs.size();
309 i = ( i + 1 ) % neighs.size(), count++ ) {
310 const auto &neigh = neighs[i];
311 if( gas_can_spread_to( cur, p, neigh.first ) ) {
312 spread.push_back( i );
313 }
314 }
315 auto maptiles = get_wind_blockers( winddirection, p );
316 // Three map tiles that are facing the wind direction.
317 const maptile remove_tile = std::get<0>( maptiles );
318 const maptile remove_tile2 = std::get<1>( maptiles );
319 const maptile remove_tile3 = std::get<2>( maptiles );
320 if( !spread.empty() && ( !zlevels || one_in( spread.size() ) ) ) {
321 // Construct the destination from offset and p
322 if( g->is_sheltered( p ) || windpower < 5 ) {
323 std::pair<tripoint, maptile> &n = neighs[ random_entry( spread ) ];
324 gas_spread_to( cur, n.second, n.first );
325 } else {
326 end_it = static_cast<size_t>( rng( 0, neighs.size() - 1 ) );
327 // Start at end_it + 1, then wrap around until all elements have been processed.
328 for( size_t i = ( end_it + 1 ) % neighs.size(), count = 0;
329 count != neighs.size();
330 i = ( i + 1 ) % neighs.size(), count++ ) {
331 const auto &neigh = neighs[i].second;
332 if( ( neigh.pos_.x != remove_tile.pos_.x && neigh.pos_.y != remove_tile.pos_.y ) ||
333 ( neigh.pos_.x != remove_tile2.pos_.x && neigh.pos_.y != remove_tile2.pos_.y ) ||
334 ( neigh.pos_.x != remove_tile3.pos_.x && neigh.pos_.y != remove_tile3.pos_.y ) ) {
335 neighbour_vec.push_back( i );
336 } else if( x_in_y( 1, std::max( 2, windpower ) ) ) {
337 neighbour_vec.push_back( i );
338 }
339 }
340 if( !neighbour_vec.empty() ) {
341 std::pair<tripoint, maptile> &n = neighs[neighbour_vec[rng( 0, neighbour_vec.size() - 1 )]];
342 gas_spread_to( cur, n.second, n.first );
343 }
344 }
345 } else if( zlevels && p.z < OVERMAP_HEIGHT ) {
346 const tripoint up{ p.xy(), p.z + 1 };
347 if( gas_can_spread_to( cur, p, up ) && valid_move( p, up, true, true ) ) {
348 maptile up_tile = maptile_at_internal( up );
349 gas_spread_to( cur, up_tile, up );
350 }
351 }
352}
std::tuple< maptile, maptile, maptile > get_wind_blockers(const int &winddirection, const tripoint &pos)
Definition: map_field.cpp:1894
bool gas_can_spread_to(field_entry &cur, const tripoint &src, const tripoint &dst)
Definition: map_field.cpp:211
void gas_spread_to(field_entry &cur, maptile &dst, const tripoint &p)
Definition: map_field.cpp:225
coords::coord_point< tripoint, coords::origin::abs, coords::omt > tripoint_abs_omt
Definition: coordinates.h:493
double get_local_windpower(double windpower, const oter_id &omter, const tripoint &location, const int &winddirection, bool sheltered)
Definition: weather.cpp:938
const field_intensity_level & get_intensity_level(int level=0) const
Definition: field_type.cpp:130
point pos_
Definition: submap.h:272
void apply_gas(const tripoint &p, const int nintensity=0)
Definition: scent_block.h:77

References scent_block::apply_gas(), detail::count(), g, gas_can_spread_to(), gas_spread_to(), field_entry::get_field_age(), field_entry::get_field_intensity(), field_entry::get_field_type(), field_type::get_intensity_level(), get_local_windpower(), get_map(), get_neighbors(), get_weather(), get_wind_blockers(), getabs(), is_outside(), maptile_at_internal(), ms_to_omt_copy(), one_in(), overmap_buffer, OVERMAP_DEPTH, OVERMAP_HEIGHT, points_in_radius(), maptile::pos_, random_entry(), rng(), field_intensity_level::scent_neutralization, field_entry::set_field_age(), overmapbuffer::ter(), valid_move(), point::x, x_in_y(), tripoint::xy(), point::y, tripoint::z, and zlevels.

Referenced by process_fields_in_submap().

◆ stored_volume()

units::volume map::stored_volume ( const tripoint p)

Definition at line 4224 of file map.cpp.

4225{
4226 return i_at( p ).stored_volume();
4227}
units::volume stored_volume() const
Total volume of the items here.
Definition: item_stack.cpp:98

References i_at(), and item_stack::stored_volume().

◆ support_dirty()

void map::support_dirty ( const tripoint p)
private

Definition at line 2267 of file map.cpp.

2268{
2269 if( zlevels ) {
2270 support_cache_dirty.insert( p );
2271 }
2272}

References support_cache_dirty, and zlevels.

Referenced by add_field(), add_item_or_charges(), drop_furniture(), furn_set(), ter_set(), and update_suspension_cache().

◆ supports_above()

bool map::supports_above ( const tripoint p) const

Does this tile support vehicles and furniture above it.

Definition at line 2020 of file map.cpp.

2021{
2022 const maptile tile = maptile_at( p );
2023 const ter_t &ter = tile.get_ter_t();
2024 if( ter.movecost == 0 ) {
2025 return true;
2026 }
2027
2028 const furn_id frn_id = tile.get_furn();
2029 if( frn_id != f_null ) {
2030 const furn_t &frn = frn_id.obj();
2031 if( frn.movecost < 0 ) {
2032 return true;
2033 }
2034 }
2035
2036 return veh_at( p ).has_value();
2037}
constexpr bool has_value() const noexcept
Definition: optional.h:123
furn_id get_furn() const
Definition: submap.h:285

References f_null, maptile::get_furn(), maptile::get_ter_t(), cata::optional< T >::has_value(), maptile_at(), map_data_common_t::movecost, int_id< T >::obj(), ter(), and veh_at().

Referenced by vehicle::check_falling_or_floating(), and drop_furniture().

◆ ter() [1/2]

ter_id map::ter ( const point p) const
inline

Definition at line 876 of file map.h.

876 {
877 return ter( tripoint( p, abs_sub.z ) );
878 }

References abs_sub, ter(), and tripoint::z.

◆ ter() [2/2]

ter_id map::ter ( const tripoint p) const

Definition at line 1498 of file map.cpp.

1499{
1500 if( !inbounds( p ) ) {
1501 return t_null;
1502 }
1503
1504 point l;
1505 submap *const current_submap = get_submap_at( p, l );
1506
1507 return current_submap->get_ter( l );
1508}

References get_submap_at(), submap::get_ter(), inbounds(), and t_null.

Referenced by computer_session::action_conveyor(), computer_session::action_data_anal(), computer_session::action_deactivate_shock_vent(), computer_session::action_elevator_on(), computer_session::action_extract_rad_source(), computer_session::action_geiger(), computer_session::action_irradiator(), computer_session::action_sample(), computer_session::action_srcf_elevator(), computer_session::action_srcf_seal(), actualize(), ter_furn_transform::add_all_messages(), add_boardable(), apply< ter_t >(), cata_event_dispatch::avatar_moves(), bash_rating(), bash_resistance(), bash_strength(), bash_ter_furn(), bash_ter_success(), board_up(), MapExtras::burned_ground_parser(), activity_handlers::burrow_finish(), can_construct(), can_do_activity_there(), can_examine_at(), iexamine::cardreader(), iexamine::cardreader_foodplace(), construct::check_deconstruct(), vehicle::autodrive_controller::check_drivable(), activity_handlers::chop_logs_finish(), chop_tree_activity(), close_door(), complete_construction(), coverage(), iexamine::curtains(), MapExtras::dead_vegetation_parser(), determine_wall_corner(), displace_water(), construct::done_deconstruct(), construct::done_digormine_stair(), construct::done_extract_maybe_revert_to_dirt(), construct::done_mine_upstair(), editmap_hilight::draw(), draw_connections(), draw_lab(), editmap::draw_main_ui_overlay(), draw_mine(), draw_temple(), draw_triffid(), avatar_action::eat_here(), explosion_handler::emp_blast(), examine(), game::examine(), game::extended_description(), computer_session::failure_destroy_data(), computer_session::failure_pump_explode(), computer_session::failure_pump_leak(), feature< ter_id >(), talk_function::field_plant(), activity_handlers::fill_liquid_do_turn(), activity_handlers::fill_pit_finish(), find_base_construction(), game::find_or_make_stairs(), find_potential_computer_point(), dig_activity_actor::finish(), dig_channel_activity_actor::finish(), hacking_activity_actor::finish(), Character::floor_bedding_warmth(), fromPumpFuel(), iexamine::fswitch(), gas_can_spread_to(), generic_multi_activity_locations(), get_changed_ids_from_update(), get_hack_type(), get_harvest(), get_harvest_names(), get_known_connections(), get_roof(), get_ter_transforms_into(), iexamine::getGasPumpByNumber(), iexamine::getNearFilledGasTank(), getNearPumpCount(), activity_handlers::hacksaw_finish(), has_flag_ter(), has_neighbor(), has_pre_terrain(), hit_with_acid(), advanced_inv_area::init(), is_bashable(), is_bashable_ter(), anonymous_namespace{gates.cpp}::gate_data::is_suitable_wall(), is_suspension_valid(), iexamine::ledge(), talk_function::loot_building(), mapgen_ants_generic(), mapgen_lake_shore(), fungal_effects::marlossify(), map_stack::max_volume(), map_funcs::migo_nerve_cage_removal(), avatar_action::move(), move_cost(), move_vehicle(), MapExtras::mx_grove(), MapExtras::mx_helicopter(), MapExtras::mx_house_spider(), MapExtras::mx_house_wasp(), MapExtras::mx_portal_in(), MapExtras::mx_shrubbery(), iexamine::nanofab(), obstacle_coverage(), om_cutdown_trees(), om_harvest_ter(), open(), open_door(), activity_handlers::oxytorch_finish(), iexamine::pedestal_wyrm(), tutorial_game::per_turn(), activity_handlers::pickaxe_finish(), iexamine::pit(), iexamine::pit_covered(), mission_start::place_deposit_box(), place_items(), game::place_player(), game::print_fields_info(), game::print_graffiti_info(), game::print_terrain_info(), process_fields_in_submap(), process_items_in_submap(), produce_sap(), activity_handlers::pry_nails_finish(), rad_scorch(), resolve_regional_terrain_and_furniture(), restock_fruits(), mission_start::reveal_lab_train_depot(), shoot(), supports_above(), ter(), tername(), gates::toggle_gate(), iexamine::toPumpFuel(), ter_furn_transform::transform(), translate(), translate_radius(), trap_set(), turnOnSelectedPump(), Character::update_bodytemp(), update_suspension_cache(), editmap::update_view_with_help(), pick_lock_actor::use(), vehicle_wheel_traction(), game::vertical_move(), game::walk_move(), and water_from().

◆ ter_set() [1/2]

bool map::ter_set ( const point p,
const ter_id new_terrain 
)
inline

Definition at line 901 of file map.h.

901 {
902 return ter_set( tripoint( p, abs_sub.z ), new_terrain );
903 }

References abs_sub, ter_set(), and tripoint::z.

◆ ter_set() [2/2]

bool map::ter_set ( const tripoint p,
const ter_id new_terrain 
)

Definition at line 1639 of file map.cpp.

1640{
1641 if( !inbounds( p ) ) {
1642 return false;
1643 }
1644
1645 point l;
1646 submap *const current_submap = get_submap_at( p, l );
1647 const ter_id old_id = current_submap->get_ter( l );
1648 if( old_id == new_terrain ) {
1649 // Nothing changed
1650 return false;
1651 }
1652
1653 current_submap->set_ter( l, new_terrain );
1654
1655 // Set the dirty flags
1656 const ter_t &old_t = old_id.obj();
1657 const ter_t &new_t = new_terrain.obj();
1658
1659 // HACK: Hack around ledges in traplocs or else it gets NASTY in z-level mode
1660 if( old_t.trap != tr_null && old_t.trap != tr_ledge ) {
1661 auto &traps = traplocs[old_t.trap.to_i()];
1662 const auto iter = std::find( traps.begin(), traps.end(), p );
1663 if( iter != traps.end() ) {
1664 traps.erase( iter );
1665 }
1666 }
1667 if( new_t.trap != tr_null && new_t.trap != tr_ledge ) {
1668 traplocs[new_t.trap.to_i()].push_back( p );
1669 }
1670
1671 if( old_t.transparent != new_t.transparent ) {
1674 }
1675
1676 if( old_t.has_flag( TFLAG_INDOORS ) != new_t.has_flag( TFLAG_INDOORS ) ) {
1678 }
1679
1680 if( new_t.has_flag( TFLAG_NO_FLOOR ) != old_t.has_flag( TFLAG_NO_FLOOR ) ) {
1682 // It's a set, not a flag
1683 support_cache_dirty.insert( p );
1685 }
1686
1687 if( new_t.has_flag( TFLAG_SUSPENDED ) != old_t.has_flag( TFLAG_SUSPENDED ) ) {
1689 if( new_t.has_flag( TFLAG_SUSPENDED ) ) {
1690 level_cache &ch = get_cache( p.z );
1691 ch.suspension_cache.emplace_back( getabs( p ).xy() );
1692 }
1693 }
1694
1696
1698
1699 // TODO: Limit to changes that affect move cost, traps and stairs
1701
1702 tripoint above( p.xy(), p.z + 1 );
1703 // Make sure that if we supported something and no longer do so, it falls down
1704 support_dirty( above );
1705
1706 return true;
1707}
std::list< point > suspension_cache
Definition: map.h:312
trap_id trap
Definition: mapdata.h:469

References detail::find(), get_cache(), get_submap_at(), submap::get_ter(), getabs(), map_data_common_t::has_flag(), inbounds(), invalidate_max_populated_zlev(), int_id< T >::obj(), set_floor_cache_dirty(), set_memory_seen_cache_dirty(), set_outside_cache_dirty(), set_pathfinding_cache_dirty(), set_seen_cache_dirty(), set_suspension_cache_dirty(), submap::set_ter(), set_transparency_cache_dirty(), support_cache_dirty, support_dirty(), level_cache::suspension_cache, TFLAG_INDOORS, TFLAG_NO_FLOOR, TFLAG_SUSPENDED, int_id< T >::to_i(), tr_ledge, tr_null, map_data_common_t::transparent, ter_t::trap, traplocs, tripoint::xy(), and tripoint::z.

Referenced by computer_session::action_elevator_on(), computer_session::action_srcf_elevator(), add_computer(), jmapgen_terrain::apply(), jmapgen_computer::apply(), jmapgen_setmap::apply(), apply< ter_t >(), bash_ter_success(), board_up(), MapExtras::burned_ground_parser(), iexamine::cardreader(), iexamine::cardreader_foodplace(), iexamine::cardreader_robofac(), activity_handlers::chop_logs_finish(), activity_handlers::chop_tree_finish(), activity_handlers::churn_finish(), close_door(), collapse_at(), collapse_invalid_suspension(), complete_construction(), iexamine::curtains(), MapExtras::dead_vegetation_parser(), displace_water(), construct::done_deconstruct(), construct::done_digormine_stair(), construct::done_extract_maybe_revert_to_dirt(), construct::done_mine_upstair(), construct::done_ramp_high(), construct::done_ramp_low(), construct::done_wood_stairs(), draw_anthill(), draw_circle_ter(), draw_connections(), draw_lab(), draw_line_ter(), draw_mine(), draw_rough_circle_ter(), draw_slimepit(), draw_square_ter(), draw_temple(), draw_triffid(), avatar_action::eat_here(), explosion_handler::emp_blast(), computer_session::failure_pump_leak(), computer_session::failure_shutdown(), farm_action(), talk_function::field_harvest(), activity_handlers::fill_pit_finish(), dig_activity_actor::finish(), dig_channel_activity_actor::finish(), hacking_activity_actor::finish(), activity_handlers::forage_finish(), game::forced_door_closing(), mapgen_function_json_base::formatted_set_incredibly_simple(), mapf::formatted_set_simple(), fromPumpFuel(), iexamine::fswitch(), activity_handlers::hacksaw_finish(), iexamine::harvest_plant(), iexamine::harvest_ter(), iexamine::harvest_ter_nectar(), hit_with_acid(), talk_function::loot_building(), make_rubble(), mapgen_ants_curved(), mapgen_ants_four_way(), mapgen_ants_generic(), mapgen_ants_straight(), mapgen_ants_tee(), mapgen_cavern(), mapgen_crater(), mapgen_field(), mapgen_forest_trail_curved(), mapgen_forest_trail_four_way(), mapgen_forest_trail_straight(), mapgen_forest_trail_tee(), mapgen_hellmouth(), mapgen_highway(), mapgen_hive(), mapgen_lake_shore(), mapgen_null(), mapgen_parking_lot(), mapgen_rift(), mapgen_river_curved(), mapgen_river_curved_not(), mapgen_river_straight(), mapgen_road(), mapgen_rock_partial(), mapgen_sewer_curved(), mapgen_sewer_four_way(), mapgen_sewer_straight(), mapgen_sewer_tee(), mapgen_test(), mapgen_tutorial(), fungal_effects::marlossify(), map_funcs::migo_nerve_cage_removal(), move_vehicle(), MapExtras::mx_bandits_block(), MapExtras::mx_clay_deposit(), MapExtras::mx_clearcut(), MapExtras::mx_grave(), MapExtras::mx_grove(), MapExtras::mx_helicopter(), MapExtras::mx_house_wasp(), MapExtras::mx_pond(), MapExtras::mx_portal_in(), MapExtras::mx_roadblock(), MapExtras::mx_shrubbery(), MapExtras::mx_spider(), om_cutdown_trees(), om_harvest_ter(), om_set_hide_site(), open_door(), activity_handlers::oxytorch_finish(), iexamine::pedestal_temple(), iexamine::pedestal_wyrm(), pick_plant(), iexamine::pit(), iexamine::pit_covered(), MapExtras::place_fumarole(), place_gas_pump(), mission_start::place_npc_software(), process_fields_in_submap(), activity_handlers::pry_nails_finish(), rad_scorch(), mission_start::ranch_nurse_4(), mission_start::ranch_nurse_5(), mission_start::ranch_scavenger_2(), mission_start::ranch_scavenger_3(), resolve_regional_terrain_and_furniture(), restock_fruits(), science_room(), set(), iexamine::shrub_marloss(), fungal_effects::spread_fungus_one_tile(), ter_or_furn_set(), ter_set(), gates::toggle_gate(), iexamine::toPumpFuel(), ter_furn_transform::transform(), translate(), translate_radius(), iexamine::tree_hickory(), iexamine::tree_maple(), iexamine::tree_maple_tapped(), iexamine::tree_marloss(), turnOnSelectedPump(), and game::vertical_move().

◆ tername() [1/2]

std::string map::tername ( const point p) const
inline

Definition at line 906 of file map.h.

906 {
907 return tername( tripoint( p, abs_sub.z ) );
908 }

References abs_sub, tername(), and tripoint::z.

◆ tername() [2/2]

◆ tinder_at()

bool map::tinder_at ( const tripoint p)

Checks if there are any tinder flagged items on the tile.

Parameters
ptile to check

Definition at line 2626 of file map.cpp.

2627{
2628 for( const auto &i : i_at( p ) ) {
2629 if( i.has_flag( "TINDER" ) ) {
2630 return true;
2631 }
2632 }
2633 return false;
2634}

References i_at().

Referenced by activity_handlers::start_fire_do_turn().

◆ tr_at()

◆ translate()

void map::translate ( const ter_id from,
const ter_id to 
)

Definition at line 3933 of file map.cpp.

3934{
3935 if( from == to ) {
3936 debugmsg( "map::translate %s => %s",
3937 from.obj().name(),
3938 from.obj().name() );
3939 return;
3940 }
3941 for( const tripoint &p : points_on_zlevel() ) {
3942 if( ter( p ) == from ) {
3943 ter_set( p, to );
3944 }
3945 }
3946}

References debugmsg, map_data_common_t::name(), int_id< T >::obj(), points_on_zlevel(), ter(), and ter_set().

Referenced by jmapgen_translate::apply(), mapgen_lake_shore(), start_location::prepare_map(), mission_start::ranch_nurse_5(), mission_start::ranch_nurse_6(), mission_start::ranch_nurse_7(), mission_start::ranch_nurse_8(), and mission_start::ranch_scavenger_3().

◆ translate_radius()

void map::translate_radius ( const ter_id from,
const ter_id to,
float  radi,
const tripoint p,
bool  same_submap = false,
bool  toggle_between = false 
)

Definition at line 3949 of file map.cpp.

3951{
3952 if( from == to ) {
3953 debugmsg( "map::translate %s => %s", from.obj().name(), to.obj().name() );
3954 return;
3955 }
3956
3957 const tripoint abs_omt_p = ms_to_omt_copy( getabs( p ) );
3958 for( const tripoint &t : points_on_zlevel() ) {
3959 const tripoint abs_omt_t = ms_to_omt_copy( getabs( t ) );
3960 const float radiX = trig_dist( p, t );
3961 if( ter( t ) == from ) {
3962 // within distance, and either no submap limitation or same overmap coords.
3963 if( radiX <= radi && ( !same_submap || abs_omt_t == abs_omt_p ) ) {
3964 ter_set( t, to );
3965 }
3966 } else if( toggle_between && ter( t ) == to ) {
3967 if( radiX <= radi && ( !same_submap || abs_omt_t == abs_omt_p ) ) {
3968 ter_set( t, from );
3969 }
3970 }
3971 }
3972}

References debugmsg, getabs(), ms_to_omt_copy(), map_data_common_t::name(), int_id< T >::obj(), points_on_zlevel(), ter(), ter_set(), and trig_dist().

Referenced by computer_session::action_extract_rad_source(), computer_session::action_irradiator(), computer_session::action_lock(), computer_session::action_open(), computer_session::action_release(), computer_session::action_release_bionics(), computer_session::action_shutters(), and computer_session::action_unlock().

◆ trap_locations()

const std::vector< tripoint > & map::trap_locations ( const trap_id type) const

Definition at line 7764 of file map.cpp.

7765{
7766 return traplocs[type.to_i()];
7767}

References traplocs, and type.

◆ trap_set()

void map::trap_set ( const tripoint p,
const trap_id type 
)

Definition at line 5189 of file map.cpp.

5190{
5191 if( !inbounds( p ) ) {
5192 return;
5193 }
5194
5195 point l;
5196 submap *const current_submap = get_submap_at( p, l );
5197 const ter_t &ter = current_submap->get_ter( l ).obj();
5198 if( ter.trap != tr_null ) {
5199 debugmsg( "set trap %s on top of terrain %s which already has a builit-in trap",
5200 type.obj().name(), ter.name() );
5201 return;
5202 }
5203
5204 // If there was already a trap here, remove it.
5205 if( current_submap->get_trap( l ) != tr_null ) {
5206 remove_trap( p );
5207 }
5208
5209 current_submap->set_trap( l, type );
5210 if( type != tr_null ) {
5211 traplocs[type.to_i()].push_back( p );
5212 }
5213}
void remove_trap(const tripoint &p)
Definition: map.cpp:5273

References debugmsg, get_submap_at(), submap::get_ter(), submap::get_trap(), inbounds(), int_id< T >::obj(), remove_trap(), submap::set_trap(), ter(), tr_null, traplocs, and type.

Referenced by jmapgen_trap::apply(), apply< trap >(), construction_activity(), construct::done_mark_firewood(), construct::done_mark_practice_target(), draw_lab(), vehicle::handle_trap(), mtrap_set(), MapExtras::mx_portal(), place_and_add_as_known(), place_construction(), and explosion_handler::explosion_funcs::resonance_cascade().

◆ unboard_vehicle() [1/2]

void map::unboard_vehicle ( const tripoint p,
bool  dead_passenger = false 
)

Definition at line 1101 of file map.cpp.

1102{
1104 player *passenger = nullptr;
1105 if( !vp ) {
1106 debugmsg( "map::unboard_vehicle: vehicle not found" );
1107 // Try and force unboard the player anyway.
1108 passenger = g->critter_at<player>( p );
1109 if( passenger ) {
1110 passenger->in_vehicle = false;
1111 passenger->controlling_vehicle = false;
1112 }
1113 return;
1114 }
1115 passenger = vp->get_passenger();
1116 unboard_vehicle( *vp, passenger, dead_passenger );
1117}
bool controlling_vehicle
Definition: character.h:228

References Character::controlling_vehicle, debugmsg, g, Character::in_vehicle, optional_vpart_position::part_with_feature(), unboard_vehicle(), veh_at(), and VPFLAG_BOARDABLE.

◆ unboard_vehicle() [2/2]

void map::unboard_vehicle ( const vpart_reference vp,
Character passenger,
bool  dead_passenger = false 
)

Definition at line 1081 of file map.cpp.

1082{
1083 // Mark the part as un-occupied regardless of whether there's a live passenger here.
1085 vp.vehicle().invalidate_mass();
1086
1087 if( !passenger ) {
1088 if( !dead_passenger ) {
1089 debugmsg( "map::unboard_vehicle: passenger not found" );
1090 }
1091 return;
1092 }
1093 passenger->in_vehicle = false;
1094 // Only make vehicle go out of control if the driver is the one unboarding.
1095 if( passenger->controlling_vehicle ) {
1096 vp.vehicle().skidding = true;
1097 }
1098 passenger->controlling_vehicle = false;
1099}
void invalidate_mass()
Mark mass caches and pivot cache as dirty.
Definition: vehicle.cpp:6968
vehicle_part & part() const
Yields the vehicle_part object referenced by this.
Definition: vehicle.cpp:6771
::vehicle & vehicle() const

References Character::controlling_vehicle, debugmsg, Character::in_vehicle, vehicle::invalidate_mass(), vpart_reference::part(), vehicle_part::passenger_flag, vehicle_part::remove_flag(), vehicle::skidding, and vpart_reference::vehicle().

Referenced by board_vehicle(), iexamine::chainfence(), detach_vehicle(), game::fling_creature(), talk_function::individual_mission(), game::is_game_over(), npc::move_to(), game::moving_vehicle_dismount(), game::phasing_move(), game::place_player(), game::place_player_overmap(), mattack::ranged_pull(), shake_vehicle(), game::swap_critters(), avatar_action::swim(), unboard_vehicle(), and game::vertical_move().

◆ update_lum()

void map::update_lum ( item_location loc,
bool  add 
)

Update luminosity before and after item's transformation.

Definition at line 4447 of file map.cpp.

4448{
4449 item *target = loc.get_item();
4450
4451 // if the item is not emissive, do nothing
4452 if( !target->is_emissive() ) {
4453 return;
4454 }
4455
4456 point l;
4457 submap *const current_submap = get_submap_at( loc.position(), l );
4458
4459 if( add ) {
4460 current_submap->update_lum_add( l, *target );
4461 } else {
4462 current_submap->update_lum_rem( l, *target );
4463 }
4464}
bool is_emissive() const
Whether the item emits any light at all.
Definition: item.cpp:6823

References om_direction::add(), item_location::get_item(), get_submap_at(), item::is_emissive(), item_location::position(), submap::update_lum_add(), and submap::update_lum_rem().

Referenced by update_lum().

◆ update_pathfinding_cache()

void map::update_pathfinding_cache ( int  zlev) const

Definition at line 8821 of file map.cpp.

8822{
8823 auto &cache = get_pathfinding_cache( zlev );
8824 if( !cache.dirty ) {
8825 return;
8826 }
8827
8828 std::uninitialized_fill_n( &cache.special[0][0], MAPSIZE_X * MAPSIZE_Y, PF_NORMAL );
8829
8830 for( int smx = 0; smx < my_MAPSIZE; ++smx ) {
8831 for( int smy = 0; smy < my_MAPSIZE; ++smy ) {
8832 const auto cur_submap = get_submap_at_grid( { smx, smy, zlev } );
8833 if( !cur_submap ) {
8834 return;
8835 }
8836
8837 tripoint p( 0, 0, zlev );
8838
8839 for( int sx = 0; sx < SEEX; ++sx ) {
8840 p.x = sx + smx * SEEX;
8841 for( int sy = 0; sy < SEEY; ++sy ) {
8842 p.y = sy + smy * SEEY;
8843
8844 pf_special cur_value = PF_NORMAL;
8845
8846 maptile tile( cur_submap, point( sx, sy ) );
8847
8848 const auto &terrain = tile.get_ter_t();
8849 const auto &furniture = tile.get_furn_t();
8850 int part;
8851 const vehicle *veh = veh_at_internal( p, part );
8852
8853 const int cost = move_cost_internal( furniture, terrain, veh, part );
8854
8855 if( cost > 2 ) {
8856 cur_value |= PF_SLOW;
8857 } else if( cost <= 0 ) {
8858 cur_value |= PF_WALL;
8859 if( terrain.has_flag( TFLAG_CLIMBABLE ) ) {
8860 cur_value |= PF_CLIMBABLE;
8861 }
8862 }
8863
8864 if( veh != nullptr ) {
8865 cur_value |= PF_VEHICLE;
8866 }
8867
8868 for( const auto &fld : tile.get_field() ) {
8869 const field_entry &cur = fld.second;
8870 const field_type_id type = cur.get_field_type();
8871 const int field_intensity = cur.get_field_intensity();
8872 if( type.obj().get_dangerous( field_intensity - 1 ) ) {
8873 cur_value |= PF_FIELD;
8874 }
8875 }
8876
8877 if( !tile.get_trap_t().is_benign() || !terrain.trap.obj().is_benign() ) {
8878 cur_value |= PF_TRAP;
8879 }
8880
8881 if( terrain.has_flag( TFLAG_GOES_DOWN ) || terrain.has_flag( TFLAG_GOES_UP ) ||
8882 terrain.has_flag( TFLAG_RAMP ) || terrain.has_flag( TFLAG_RAMP_UP ) ||
8883 terrain.has_flag( TFLAG_RAMP_DOWN ) ) {
8884 cur_value |= PF_UPDOWN;
8885 }
8886
8887 if( terrain.has_flag( TFLAG_SHARP ) ) {
8888 cur_value |= PF_SHARP;
8889 }
8890
8891 cache.special[p.x][p.y] = cur_value;
8892 }
8893 }
8894 }
8895 }
8896
8897 cache.dirty = false;
8898}
@ TFLAG_CLIMBABLE
Definition: mapdata.h:307
@ TFLAG_SHARP
Definition: mapdata.h:296
pf_special
Definition: pathfinding.h:7
@ PF_NORMAL
Definition: pathfinding.h:8
@ PF_FIELD
Definition: pathfinding.h:12

References furniture, maptile::get_field(), field_entry::get_field_intensity(), field_entry::get_field_type(), maptile::get_furn_t(), get_pathfinding_cache(), get_submap_at_grid(), maptile::get_ter_t(), maptile::get_trap_t(), trap::is_benign(), MAPSIZE_X, MAPSIZE_Y, move_cost_internal(), my_MAPSIZE, PF_CLIMBABLE, PF_FIELD, PF_NORMAL, PF_SHARP, PF_SLOW, PF_TRAP, PF_UPDOWN, PF_VEHICLE, PF_WALL, SEEX, SEEY, sx, sy, terrain, TFLAG_CLIMBABLE, TFLAG_GOES_DOWN, TFLAG_GOES_UP, TFLAG_RAMP, TFLAG_RAMP_DOWN, TFLAG_RAMP_UP, TFLAG_SHARP, type, veh_at_internal(), tripoint::x, and tripoint::y.

Referenced by get_pathfinding_cache_ref().

◆ update_submap_active_item_status()

void map::update_submap_active_item_status ( const tripoint p)

Definition at line 5599 of file map.cpp.

5600{
5601 point l;
5602 submap *const current_submap = get_submap_at( p, l );
5603 if( current_submap->active_items.empty() ) {
5604 submaps_with_active_items.erase( tripoint( abs_sub.x + p.x / SEEX, abs_sub.y + p.y / SEEY, p.z ) );
5605 }
5606}

References abs_sub, submap::active_items, active_item_cache::empty(), get_submap_at(), SEEX, SEEY, submaps_with_active_items, tripoint::x, tripoint::y, and tripoint::z.

◆ update_suspension_cache()

void map::update_suspension_cache ( const int &  z)

Definition at line 8071 of file map.cpp.

8072{
8073 level_cache &ch = get_cache( z );
8074 if( !ch.suspension_cache_dirty ) {
8075 return;
8076 }
8077 std::list<point> &suspension_cache = ch.suspension_cache;
8079 for( int smx = 0; smx < my_MAPSIZE; ++smx ) {
8080 for( int smy = 0; smy < my_MAPSIZE; ++smy ) {
8081 const submap *cur_submap = get_submap_at_grid( { smx, smy, z } );
8082
8083 if( cur_submap == nullptr ) {
8084 debugmsg( "Tried to run suspension check at (%d,%d,%d) but the submap is not loaded", smx, smy,
8085 z );
8086 continue;
8087 }
8088
8089 for( int sx = 0; sx < SEEX; ++sx ) {
8090 for( int sy = 0; sy < SEEY; ++sy ) {
8091 point sp( sx, sy );
8092 const ter_t &terrain = cur_submap->get_ter( sp ).obj();
8093 if( terrain.has_flag( TFLAG_SUSPENDED ) ) {
8094 tripoint loc( coords::project_combine( point_om_sm( point( smx, smy ) ), point_sm_ms( sp ) ).raw(),
8095 z );
8096 suspension_cache.emplace_back( getabs( loc ).xy() );
8097 }
8098 }
8099 }
8100 }
8101 }
8103 }
8104
8105 for( auto iter = suspension_cache.begin(); iter != suspension_cache.end(); ) {
8106 const point absp = *iter;
8107 const point locp = getlocal( absp );
8108 const tripoint loctp( locp, z );
8109 if( !inbounds( locp ) ) {
8110 ++iter;
8111 continue;
8112 }
8113 const submap *cur_submap = get_submap_at( loctp );
8114 if( cur_submap == nullptr ) {
8115 debugmsg( "Tried to run suspension check at (%d,%d,%d) but the submap is not loaded", locp.x,
8116 locp.y, z );
8117 ++iter;
8118 continue;
8119 }
8120 const ter_t &terrain = ter( locp ).obj();
8121 if( terrain.has_flag( TFLAG_SUSPENDED ) ) {
8122 if( !is_suspension_valid( loctp ) ) {
8123 support_dirty( loctp );
8124 iter = suspension_cache.erase( iter );
8125 } else {
8126 ++iter;
8127 }
8128 } else {
8129 iter = suspension_cache.erase( iter );
8130 }
8131 }
8132 ch.suspension_cache_dirty = false;
8133}
coords::coord_point< point, coords::origin::overmap, coords::sm > point_om_sm
Definition: coordinates.h:477
auto project_combine(const coord_point< PointL, CoarseOrigin, CoarseScale > &coarse, const coord_point< PointR, FineOrigin, FineScale > &fine)
Definition: coordinates.h:413
bool suspension_cache_initialized
Definition: map.h:310

References debugmsg, get_cache(), get_submap_at(), get_submap_at_grid(), submap::get_ter(), getabs(), getlocal(), inbounds(), is_suspension_valid(), my_MAPSIZE, int_id< T >::obj(), coords::project_combine(), SEEX, SEEY, support_dirty(), level_cache::suspension_cache, level_cache::suspension_cache_dirty, level_cache::suspension_cache_initialized, sx, sy, ter(), terrain, TFLAG_SUSPENDED, point::x, and point::y.

Referenced by build_map_cache().

◆ update_vehicle_cache()

void map::update_vehicle_cache ( vehicle ,
int  old_zlevel 
)

◆ update_vehicle_list()

void map::update_vehicle_list ( const submap to,
int  zlev 
)

Definition at line 340 of file map.cpp.

341{
342 // Update vehicle data
343 level_cache &ch = get_cache( zlev );
344 for( const auto &elem : to->vehicles ) {
345 ch.vehicle_list.insert( elem.get() );
346 if( !elem->loot_zones.empty() ) {
347 ch.zone_vehicles.insert( elem.get() );
348 }
349 }
350
352}

References get_cache(), last_full_vehicle_list_dirty, level_cache::vehicle_list, submap::vehicles, and level_cache::zone_vehicles.

Referenced by displace_vehicle(), editmap::mapgen_preview(), rotate(), shift(), and shift_vehicle_z().

◆ update_visibility_cache()

void map::update_visibility_cache ( int  zlev)

Definition at line 5608 of file map.cpp.

5609{
5610 visibility_variables_cache.variables_set = true; // Not used yet
5611 visibility_variables_cache.g_light_level = static_cast<int>( g->light_level( zlev ) );
5612 visibility_variables_cache.vision_threshold = g->u.get_vision_threshold(
5613 get_cache_ref( g->u.posz() ).lm[g->u.posx()][g->u.posy()].max() );
5614
5615 visibility_variables_cache.u_clairvoyance = g->u.clairvoyance();
5616 visibility_variables_cache.u_sight_impaired = g->u.sight_impaired();
5618
5619 int sm_squares_seen[MAPSIZE][MAPSIZE];
5620 std::memset( sm_squares_seen, 0, sizeof( sm_squares_seen ) );
5621
5622 int min_z = fov_3d ? -OVERMAP_DEPTH : zlev;
5623 int max_z = fov_3d ? OVERMAP_HEIGHT : zlev;
5624
5625 for( int z = min_z; z <= max_z; z++ ) {
5626
5627 auto &visibility_cache = get_cache( z ).visibility_cache;
5628
5629 tripoint p;
5630 p.z = z;
5631 int &x = p.x;
5632 int &y = p.y;
5633 for( x = 0; x < MAPSIZE_X; x++ ) {
5634 for( y = 0; y < MAPSIZE_Y; y++ ) {
5636 visibility_cache[x][y] = ll;
5637 if( z == zlev ) {
5638 sm_squares_seen[ x / SEEX ][ y / SEEY ] += ( ll == lit_level::BRIGHT || ll == lit_level::LIT );
5639 }
5640 }
5641 }
5642 }
5643
5644 for( int gridx = 0; gridx < my_MAPSIZE; gridx++ ) {
5645 for( int gridy = 0; gridy < my_MAPSIZE; gridy++ ) {
5646 if( sm_squares_seen[gridx][gridy] > 36 ) { // 25% of the submap is visible
5647 const tripoint sm( gridx, gridy, 0 );
5648 const auto abs_sm = map::abs_sub + sm;
5649 // TODO: fix point types
5650 const tripoint_abs_omt abs_omt( sm_to_omt_copy( abs_sm ) );
5651 overmap_buffer.set_seen( abs_omt, true );
5652 }
5653 }
5654 }
5655}
lit_level apparent_light_at(const tripoint &p, const visibility_variables &cache) const
Determine the visible light level for a tile, based on light_at for the tile, vision distance,...
Definition: lightmap.cpp:729
void set_seen(const tripoint_abs_omt &p, bool seen=true)
static const efftype_id effect_boomered("boomered")
bool variables_set
Definition: map.h:122
bool u_sight_impaired
Definition: map.h:123

References abs_sub, apparent_light_at(), BRIGHT, effect_boomered, fov_3d, g, visibility_variables::g_light_level, get_cache(), get_cache_ref(), LIT, level_cache::lm, MAPSIZE, MAPSIZE_X, MAPSIZE_Y, four_quadrants::max(), my_MAPSIZE, overmap_buffer, OVERMAP_DEPTH, OVERMAP_HEIGHT, SEEX, SEEY, overmapbuffer::set_seen(), coords::sm, sm_to_omt_copy(), visibility_variables::u_clairvoyance, visibility_variables::u_is_boomered, visibility_variables::u_sight_impaired, visibility_variables::variables_set, level_cache::visibility_cache, visibility_variables_cache, visibility_variables::vision_threshold, tripoint::x, tripoint::y, and tripoint::z.

Referenced by game::draw(), draw(), game::get_player_input(), and game::look_around().

◆ use_amount()

std::list< item > map::use_amount ( const tripoint origin,
int  range,
const itype_id type,
int &  quantity,
const std::function< bool(const item &)> &  filter = return_true<item> 
)

Definition at line 4820 of file map.cpp.

4822{
4823 std::list<item> ret;
4824 for( int radius = 0; radius <= range && quantity > 0; radius++ ) {
4825 for( const tripoint &p : points_in_radius( origin, radius ) ) {
4826 if( rl_dist( origin, p ) >= radius ) {
4827 std::list<item> tmp = use_amount_square( p, type, quantity, filter );
4828 ret.splice( ret.end(), tmp );
4829 }
4830 }
4831 }
4832 return ret;
4833}
std::list< item > use_amount_square(const tripoint &p, const itype_id &type, int &quantity, const std::function< bool(const item &)> &filter=return_true< item >)
Definition: map.cpp:4798

References points_in_radius(), cata::hash64_detail::ret, rl_dist(), type, and use_amount_square().

◆ use_amount_square()

std::list< item > map::use_amount_square ( const tripoint p,
const itype_id type,
int &  quantity,
const std::function< bool(const item &)> &  filter = return_true<item> 
)

Definition at line 4798 of file map.cpp.

4800{
4801 std::list<item> ret;
4802 // Handle infinite map sources.
4803 item water = water_from( p );
4804 if( water.typeId() == type ) {
4805 ret.push_back( water );
4806 quantity = 0;
4807 return ret;
4808 }
4809
4810 if( const cata::optional<vpart_reference> vp = veh_at( p ).part_with_feature( "CARGO", true ) ) {
4811 std::list<item> tmp = use_amount_stack( vp->vehicle().get_items( vp->part_index() ), type,
4812 quantity, filter );
4813 ret.splice( ret.end(), tmp );
4814 }
4815 std::list<item> tmp = use_amount_stack( i_at( p ), type, quantity, filter );
4816 ret.splice( ret.end(), tmp );
4817 return ret;
4818}
item water_from(const tripoint &p)
Definition: map.cpp:4386
std::list< item > use_amount_stack(Stack stack, const itype_id &type, int &quantity, const std::function< bool(const item &)> &filter)
Definition: map.cpp:4784

References i_at(), cata::hash64_detail::ret, type, item::typeId(), use_amount_stack(), veh_at(), and water_from().

Referenced by use_amount().

◆ use_charges()

std::list< item > map::use_charges ( const tripoint origin,
int  range,
const itype_id type,
int &  quantity,
const std::function< bool(const item &)> &  filter = return_true<item>,
basecamp bcp = nullptr 
)

Definition at line 4916 of file map.cpp.

4919{
4920 std::list<item> ret;
4921
4922 // populate a grid of spots that can be reached
4923 std::vector<tripoint> reachable_pts;
4924 reachable_flood_steps( reachable_pts, origin, range, 1, 100 );
4925
4926 // We prefer infinite map sources where available, so search for those
4927 // first
4928 for( const tripoint &p : reachable_pts ) {
4929 // Handle infinite map sources.
4930 item water = water_from( p );
4931 if( water.typeId() == type ) {
4932 water.charges = quantity;
4933 ret.push_back( water );
4934 quantity = 0;
4935 return ret;
4936 }
4937 }
4938
4939 if( bcp ) {
4940 ret = bcp->use_charges( type, quantity );
4941 if( quantity <= 0 ) {
4942 return ret;
4943 }
4944 }
4945
4946 for( const tripoint &p : reachable_pts ) {
4947 if( has_furn( p ) ) {
4948 use_charges_from_furn( furn( p ).obj(), type, quantity, this, p, ret, filter );
4949 if( quantity <= 0 ) {
4950 return ret;
4951 }
4952 }
4953
4954 if( accessible_items( p ) ) {
4955 std::list<item> tmp = use_charges_from_stack( i_at( p ), type, quantity, p, filter );
4956 ret.splice( ret.end(), tmp );
4957 if( quantity <= 0 ) {
4958 return ret;
4959 }
4960 }
4961
4962 const optional_vpart_position vp = veh_at( p );
4963 if( !vp ) {
4964 continue;
4965 }
4966
4967 const cata::optional<vpart_reference> kpart = vp.part_with_feature( "FAUCET", true );
4968 const cata::optional<vpart_reference> weldpart = vp.part_with_feature( "WELDRIG", true );
4969 const cata::optional<vpart_reference> craftpart = vp.part_with_feature( "CRAFTRIG", true );
4970 const cata::optional<vpart_reference> forgepart = vp.part_with_feature( "FORGE", true );
4971 const cata::optional<vpart_reference> kilnpart = vp.part_with_feature( "KILN", true );
4972 const cata::optional<vpart_reference> chempart = vp.part_with_feature( "CHEMLAB", true );
4973 const cata::optional<vpart_reference> autoclavepart = vp.part_with_feature( "AUTOCLAVE", true );
4974 const cata::optional<vpart_reference> autodocpart = vp.part_with_feature( "AUTODOC", true );
4975 const cata::optional<vpart_reference> cargo = vp.part_with_feature( "CARGO", true );
4976
4977 if( kpart ) { // we have a faucet, now to see what to drain
4978 itype_id ftype = itype_id::NULL_ID();
4979
4980 // Special case hotplates which draw battery power
4981 if( type == itype_hotplate ) {
4982 ftype = itype_battery;
4983 } else {
4984 ftype = type;
4985 }
4986
4987 // TODO: add a sane birthday arg
4989 tmp.charges = kpart->vehicle().drain( ftype, quantity );
4990 // TODO: Handle water poison when crafting starts respecting it
4991 quantity -= tmp.charges;
4992 ret.push_back( tmp );
4993
4994 if( quantity == 0 ) {
4995 return ret;
4996 }
4997 }
4998
4999 if( weldpart ) { // we have a weldrig, now to see what to drain
5000 itype_id ftype = itype_id::NULL_ID();
5001
5002 if( type == itype_welder ) {
5003 ftype = itype_battery;
5004 } else if( type == itype_soldering_iron ) {
5005 ftype = itype_battery;
5006 }
5007 // TODO: add a sane birthday arg
5009 tmp.charges = weldpart->vehicle().drain( ftype, quantity );
5010 quantity -= tmp.charges;
5011 ret.push_back( tmp );
5012
5013 if( quantity == 0 ) {
5014 return ret;
5015 }
5016 }
5017
5018 if( craftpart ) { // we have a craftrig, now to see what to drain
5019 itype_id ftype = itype_id::NULL_ID();
5020
5021 if( type == itype_press ) {
5022 ftype = itype_battery;
5023 } else if( type == itype_vac_sealer ) {
5024 ftype = itype_battery;
5025 } else if( type == itype_dehydrator ) {
5026 ftype = itype_battery;
5027 } else if( type == itype_food_processor ) {
5028 ftype = itype_battery;
5029 }
5030
5031 // TODO: add a sane birthday arg
5033 tmp.charges = craftpart->vehicle().drain( ftype, quantity );
5034 quantity -= tmp.charges;
5035 ret.push_back( tmp );
5036
5037 if( quantity == 0 ) {
5038 return ret;
5039 }
5040 }
5041
5042 if( forgepart ) { // we have a veh_forge, now to see what to drain
5043 itype_id ftype = itype_id::NULL_ID();
5044
5045 if( type == itype_forge ) {
5046 ftype = itype_battery;
5047 }
5048
5049 // TODO: add a sane birthday arg
5051 tmp.charges = forgepart->vehicle().drain( ftype, quantity );
5052 quantity -= tmp.charges;
5053 ret.push_back( tmp );
5054
5055 if( quantity == 0 ) {
5056 return ret;
5057 }
5058 }
5059
5060 if( kilnpart ) { // we have a veh_kiln, now to see what to drain
5061 itype_id ftype = itype_id::NULL_ID();
5062
5063 if( type == itype_kiln ) {
5064 ftype = itype_battery;
5065 }
5066
5067 // TODO: add a sane birthday arg
5069 tmp.charges = kilnpart->vehicle().drain( ftype, quantity );
5070 quantity -= tmp.charges;
5071 ret.push_back( tmp );
5072
5073 if( quantity == 0 ) {
5074 return ret;
5075 }
5076 }
5077
5078 if( chempart ) { // we have a chem_lab, now to see what to drain
5079 itype_id ftype = itype_id::NULL_ID();
5080
5081 if( type == itype_chemistry_set ) {
5082 ftype = itype_battery;
5083 } else if( type == itype_hotplate ) {
5084 ftype = itype_battery;
5085 } else if( type == itype_electrolysis_kit ) {
5086 ftype = itype_battery;
5087 }
5088
5089 // TODO: add a sane birthday arg
5091 tmp.charges = chempart->vehicle().drain( ftype, quantity );
5092 quantity -= tmp.charges;
5093 ret.push_back( tmp );
5094
5095 if( quantity == 0 ) {
5096 return ret;
5097 }
5098 }
5099
5100 if( autoclavepart ) { // we have an autoclave, now to see what to drain
5101 itype_id ftype = itype_id::NULL_ID();
5102
5103 if( type == itype_autoclave ) {
5104 ftype = itype_battery;
5105 }
5106
5107 // TODO: add a sane birthday arg
5109 tmp.charges = autoclavepart->vehicle().drain( ftype, quantity );
5110 quantity -= tmp.charges;
5111 ret.push_back( tmp );
5112
5113 if( quantity == 0 ) {
5114 return ret;
5115 }
5116 }
5117
5118 if( cargo ) {
5119 std::list<item> tmp =
5120 use_charges_from_stack( cargo->vehicle().get_items( cargo->part_index() ), type, quantity, p,
5121 filter );
5122 ret.splice( ret.end(), tmp );
5123 if( quantity <= 0 ) {
5124 return ret;
5125 }
5126 }
5127 }
5128
5129 return ret;
5130}
std::list< item > use_charges(const itype_id &fake_id, int &quantity)
Definition: basecamp.cpp:584
bool accessible_items(const tripoint &t) const
Check whether the player can access the items located .
Definition: map.cpp:6568
void reachable_flood_steps(std::vector< tripoint > &reachable_pts, const tripoint &f, int range, int cost_min, int cost_max) const
Populates a vector of points that are reachable within a number of steps from a point.
Definition: map.cpp:6297
static const itype_id itype_autoclave("autoclave")
static void use_charges_from_furn(const furn_t &f, const itype_id &type, int &quantity, map *m, const tripoint &p, std::list< item > &ret, const std::function< bool(const item &)> &filter)
Definition: map.cpp:4850
static const itype_id itype_soldering_iron("soldering_iron")
static const itype_id itype_chemistry_set("chemistry_set")
std::list< item > use_charges_from_stack(Stack stack, const itype_id &type, int &quantity, const tripoint &pos, const std::function< bool(const item &)> &filter)
Definition: map.cpp:4836
static const itype_id itype_press("press")
static const itype_id itype_hotplate("hotplate")
static const itype_id itype_electrolysis_kit("electrolysis_kit")
static const itype_id itype_food_processor("food_processor")
static const itype_id itype_forge("forge")
static const itype_id itype_battery("battery")
static const itype_id itype_dehydrator("dehydrator")
static const itype_id itype_kiln("kiln")
static const itype_id itype_welder("welder")
static const itype_id itype_vac_sealer("vac_sealer")

References accessible_items(), item::charges, furn(), has_furn(), i_at(), itype_autoclave, itype_battery, itype_chemistry_set, itype_dehydrator, itype_electrolysis_kit, itype_food_processor, itype_forge, itype_hotplate, itype_kiln, itype_press, itype_soldering_iron, itype_vac_sealer, itype_welder, string_id< itype >::NULL_ID(), optional_vpart_position::part_with_feature(), reachable_flood_steps(), cata::hash64_detail::ret, calendar::start_of_cataclysm, type, item::typeId(), basecamp::use_charges(), use_charges_from_furn(), use_charges_from_stack(), veh_at(), and water_from().

Referenced by basecamp_action_components::consume_components(), player::consume_items(), player::consume_tools(), Character::suffer_from_asthma(), and iexamine::use_furn_fake_item().

◆ valid_move()

bool map::valid_move ( const tripoint from,
const tripoint to,
bool  bash = false,
bool  flying = false,
bool  via_ramp = false 
) const

Returns true if a creature could walk from from to to in one step.

That is, if the tiles are adjacent and either on the same z-level or connected by stairs or (in case of flying monsters) open air with no floors.

Definition at line 1861 of file map.cpp.

1863{
1864 // Used to account for the fact that older versions of GCC can trip on the if statement here.
1865 assert( to.z > std::numeric_limits<int>::min() );
1866 // Note: no need to check inbounds here, because maptile_at will do that
1867 // If oob tile is supplied, the maptile_at will be an unpassable "null" tile
1868 if( std::abs( from.x - to.x ) > 1 || std::abs( from.y - to.y ) > 1 ||
1869 std::abs( from.z - to.z ) > 1 ) {
1870 return false;
1871 }
1872
1873 if( from.z == to.z ) {
1874 // But here we need to, to prevent bashing critters
1875 return passable( to ) || ( bash && inbounds( to ) );
1876 } else if( !zlevels ) {
1877 return false;
1878 }
1879
1880 const bool going_up = from.z < to.z;
1881
1882 const tripoint &up_p = going_up ? to : from;
1883 const tripoint &down_p = going_up ? from : to;
1884
1885 const maptile up = maptile_at( up_p );
1886 const ter_t &up_ter = up.get_ter_t();
1887 if( up_ter.id.is_null() ) {
1888 return false;
1889 }
1890 // Checking for ledge is a workaround for the case when mapgen doesn't
1891 // actually make a valid ledge drop location with zlevels on, this forces
1892 // at least one zlevel drop and if down_ter is impassible it's probably
1893 // inside a wall, we could workaround that further but it's unnecessary.
1894 const bool up_is_ledge = tr_at( up_p ).loadid == tr_ledge;
1895
1896 if( up_ter.movecost == 0 ) {
1897 // Unpassable tile
1898 return false;
1899 }
1900
1901 const maptile down = maptile_at( down_p );
1902 const ter_t &down_ter = down.get_ter_t();
1903 if( down_ter.id.is_null() ) {
1904 return false;
1905 }
1906
1907 if( !up_is_ledge && down_ter.movecost == 0 ) {
1908 // Unpassable tile
1909 return false;
1910 }
1911
1912 if( !up_ter.has_flag( TFLAG_NO_FLOOR ) && !up_ter.has_flag( TFLAG_GOES_DOWN ) && !up_is_ledge &&
1913 !via_ramp ) {
1914 // Can't move from up to down
1915 if( std::abs( from.x - to.x ) == 1 || std::abs( from.y - to.y ) == 1 ) {
1916 // Break the move into two - vertical then horizontal
1917 tripoint midpoint( down_p.xy(), up_p.z );
1918 return valid_move( down_p, midpoint, bash, flying, via_ramp ) &&
1919 valid_move( midpoint, up_p, bash, flying, via_ramp );
1920 }
1921 return false;
1922 }
1923
1924 if( !flying && !down_ter.has_flag( TFLAG_GOES_UP ) && !down_ter.has_flag( TFLAG_RAMP ) &&
1925 !up_is_ledge && !via_ramp ) {
1926 // Can't safely reach the lower tile
1927 return false;
1928 }
1929
1930 if( bash ) {
1931 return true;
1932 }
1933
1934 int part_up;
1935 const vehicle *veh_up = veh_at_internal( up_p, part_up );
1936 if( veh_up != nullptr ) {
1937 // TODO: Hatches below the vehicle, passable frames
1938 return false;
1939 }
1940
1941 int part_down;
1942 const vehicle *veh_down = veh_at_internal( down_p, part_down );
1943 if( veh_down != nullptr && veh_down->roof_at_part( part_down ) >= 0 ) {
1944 // TODO: OPEN (and only open) hatches from above
1945 return false;
1946 }
1947
1948 // Currently only furniture can block movement if everything else is OK
1949 // TODO: Vehicles with boards in the given spot
1950 return up.get_furn_t().movecost >= 0;
1951}
coords::coord_point< Point, Origin, Scale > midpoint(const coords::coord_point< Point, Origin, Scale > &loc1, const coords::coord_point< Point, Origin, Scale > &loc2)
Definition: coordinates.h:562
trap_id loadid
Definition: trap.h:88

References bash(), map_data_common_t::has_flag(), ter_t::id, inbounds(), string_id< T >::is_null(), trap::loadid, maptile_at(), midpoint(), map_data_common_t::movecost, passable(), vehicle::roof_at_part(), TFLAG_GOES_DOWN, TFLAG_GOES_UP, TFLAG_NO_FLOOR, TFLAG_RAMP, tr_at(), tr_ledge, valid_move(), veh_at_internal(), tripoint::x, tripoint::xy(), tripoint::y, tripoint::z, and zlevels.

Referenced by map_funcs::climbing_cost(), combined_movecost(), explosion_handler::do_blast(), draw_critter_internal(), has_floor_or_support(), scent_map::inbounds(), iexamine::ledge(), monster::move(), process_fields_in_submap(), route(), spread_gas(), monster::stumble(), and valid_move().

◆ veh_at()

optional_vpart_position map::veh_at ( const tripoint p) const

Checks if tile is occupied by vehicle and by which part.

Parameters
pTile to check for vehicle

Definition at line 1009 of file map.cpp.

1010{
1011 if( !inbounds( p ) || !const_cast<map *>( this )->get_cache( p.z ).veh_in_active_range ) {
1013 }
1014
1015 int part_num = 1;
1016 vehicle *const veh = const_cast<map *>( this )->veh_at_internal( p, part_num );
1017 if( !veh ) {
1019 }
1020 return optional_vpart_position( vpart_position( *veh, part_num ) );
1021
1022}
static constexpr nullopt_t nullopt
Definition: optional.h:22

References get_cache(), inbounds(), cata::nullopt, veh_at_internal(), level_cache::veh_in_active_range, and tripoint::z.

Referenced by Character::activate_bionic(), activity_on_turn_move_loot(), zone_manager::add(), add_splatter(), add_vehicle_to_map(), apply_faction_ownership(), are_requirements_nearby(), Creature::auto_find_hostile_target(), Character::base_comfort_value(), bash(), bash_rating(), bash_vehicle(), board_vehicle(), build_seen_cache(), build_vision_transparency_cache(), VehicleSpawnFunction::builtin_parkinglot(), Character::burn_fuel(), can_do_activity_there(), can_examine_at(), can_interact_at(), can_pickup_at(), can_put_items(), can_use_bipod(), check_art_charge_req(), vehicle::autodrive_controller::check_drivable(), player::check_eligible_containers_for_crafting(), construct::check_empty(), vehicle::check_heli_ascend(), vehicle::check_heli_descend(), climb_difficulty(), doors::close_door(), veh_interact::complete_vehicle(), game::control_vehicle(), coverage(), creature_in_field(), crush(), cycle_action(), debug_menu::debug(), deregister_vehicle_zone(), activity_handlers::repair_activity_hack::anonymous_namespace{activity_handlers.cpp}::discharge_real_power_source(), explosion_handler::do_blast(), game::do_turn(), editmap_hilight::draw(), editmap::draw_main_ui_overlay(), drop_vehicle(), game::examine(), npc::execute_action(), ranged::expected_coverage(), fetch_activity(), activity_handlers::fill_liquid_do_turn(), find_auto_consume(), npc::find_item(), Character::find_remote_fuel(), fire(), player::fire_gun(), game::fling_creature(), Character::floor_bedding_warmth(), Character::floor_item_warmth(), game::forced_door_closing(), inventory::form_from_map(), generic_multi_activity_check_requirement(), avatar::get_book_reader(), item::get_cable_target(), game::get_dangerous_tile(), player::get_eligible_containers_for_crafting(), activity_handlers::repair_activity_hack::anonymous_namespace{activity_handlers.cpp}::get_fake_tool(), liquid_handler::get_liquid_target(), overmap_ui::get_overmap_path_to(), game::get_veh_dir_indicator_location(), grab(), game::grabbed_furn_move(), game::grabbed_veh_move(), ranged::gunmode_checks_common(), ranged::gunmode_checks_weapon(), handbrake(), game::handle_action(), handle_action_menu(), Character::has_alarm_clock(), has_flag_vpart(), has_nearby_chair(), has_nearby_table(), jmapgen_setmap::has_vehicle_collision(), mapgen_function_json_base::has_vehicle_collision(), jmapgen_alternativly< PieceType >::has_vehicle_collision(), jmapgen_sign::has_vehicle_collision(), jmapgen_vending_machine::has_vehicle_collision(), jmapgen_toilet::has_vehicle_collision(), jmapgen_gaspump::has_vehicle_collision(), jmapgen_vehicle::has_vehicle_collision(), jmapgen_trap::has_vehicle_collision(), jmapgen_furniture::has_vehicle_collision(), jmapgen_terrain::has_vehicle_collision(), jmapgen_computer::has_vehicle_collision(), jmapgen_sealed_item::has_vehicle_collision(), Character::has_watch(), haul(), Character::in_climate_control(), advanced_inv_area::init(), is_bashable(), is_driving(), weather::is_sheltered(), Character::is_snuggling(), game::load(), make_active(), mine_activity(), monster_in_field(), mop_spills(), avatar_action::move(), move_cost(), npc::move_to(), move_vehicle(), game::moving_vehicle_dismount(), MapExtras::mx_helicopter(), obstacle_coverage(), obstacle_name(), open(), open_door(), vehicle::part_collision(), Character::passive_power_gen(), liquid_handler::perform_liquid_transfer(), game::phasing_move(), npc::pick_up_item(), game::place_player(), player_in_field(), pldrive(), game::print_all_tile_info(), item::process_cable(), item::process_extinguish(), projectile_attack(), vehicle_part::properties_to_item(), put_into_vehicle_or_drop(), game::remoteveh(), DefaultRemovePartHandler::removed(), zone_manager::revert_vzones(), iexamine::rubble(), conditional_t< T >::set_is_driving(), set_item_map_or_vehicle(), shoot(), explosion_handler::shrapnel(), iexamine::shrub_wildveggies(), spell_effect::spawn_summoned_vehicle(), autodrive_activity_actor::start(), activity_handlers::start_engines_finish(), supports_above(), game::swap_critters(), avatar_action::swim(), tidy_activity(), unboard_vehicle(), Character::update_bodytemp(), editmap::update_view_with_help(), deploy_furn_actor::use(), deploy_tent_actor::use(), use_amount_square(), use_charges(), game::validate_linked_vehicles(), vehicle_activity(), activity_handlers::vehicle_finish(), vehicle_selector::vehicle_selector(), wait(), game::walk_move(), avatar_action::wield(), and workbench_crafting_speed_multiplier().

◆ veh_at_internal() [1/2]

vehicle * map::veh_at_internal ( const tripoint p,
int &  part_num 
)

Definition at line 1044 of file map.cpp.

1045{
1046 return const_cast<vehicle *>( const_cast<const map *>( this )->veh_at_internal( p, part_num ) );
1047}

References veh_at_internal().

Referenced by draw_from_above(), draw_maptile(), process_fields_in_submap(), route(), update_pathfinding_cache(), valid_move(), veh_at(), and veh_at_internal().

◆ veh_at_internal() [2/2]

const vehicle * map::veh_at_internal ( const tripoint p,
int &  part_num 
) const

Definition at line 1024 of file map.cpp.

1025{
1026 // This function is called A LOT. Move as much out of here as possible.
1027 const level_cache &ch = get_cache( p.z );
1028 if( !ch.veh_in_active_range || !ch.veh_exists_at[p.x][p.y] ) {
1029 part_num = -1;
1030 return nullptr; // Clear cache indicates no vehicle. This should optimize a great deal.
1031 }
1032
1033 const auto it = ch.veh_cached_parts.find( p );
1034 if( it != ch.veh_cached_parts.end() ) {
1035 part_num = it->second.second;
1036 return it->second.first;
1037 }
1038
1039 debugmsg( "vehicle part cache indicated vehicle not found: %d %d %d", p.x, p.y, p.z );
1040 part_num = -1;
1041 return nullptr;
1042}

References debugmsg, get_cache(), level_cache::veh_cached_parts, level_cache::veh_exists_at, level_cache::veh_in_active_range, tripoint::x, tripoint::y, and tripoint::z.

◆ vehicle_vehicle_collision()

float map::vehicle_vehicle_collision ( vehicle veh,
vehicle veh2,
const std::vector< veh_collision > &  collisions 
)

Definition at line 762 of file map.cpp.

764{
765 if( &veh == &veh2 ) {
766 debugmsg( "Vehicle %s collided with itself", veh.name );
767 return 0.0f;
768 }
769
770 // Effects of colliding with another vehicle:
771 // transfers of momentum, skidding,
772 // parts are damaged/broken on both sides,
773 // remaining times are normalized
774 const veh_collision &c = collisions[0];
775 add_msg( m_bad, _( "The %1$s's %2$s collides with %3$s's %4$s." ),
776 veh.name, veh.part_info( c.part ).name(),
777 veh2.name, veh2.part_info( c.target_part ).name() );
778
779 const bool vertical = veh.sm_pos.z != veh2.sm_pos.z;
780
781 // Used to calculate the epicenter of the collision.
782 point epicenter1;
783 point epicenter2;
784
785 float dmg;
786 // Vertical collisions will be simpler for a while (1D)
787 if( !vertical ) {
788 // For reference, a cargo truck weighs ~25300, a bicycle 690,
789 // and 38mph is 3800 'velocity'
790 rl_vec2d velo_veh1 = veh.velo_vec();
791 rl_vec2d velo_veh2 = veh2.velo_vec();
792 const float m1 = to_kilogram( veh.total_mass() );
793 const float m2 = to_kilogram( veh2.total_mass() );
794 //Energy of vehicle1 and vehicle2 before collision
795 float E = 0.5 * m1 * velo_veh1.magnitude() * velo_veh1.magnitude() +
796 0.5 * m2 * velo_veh2.magnitude() * velo_veh2.magnitude();
797
798 // Collision_axis
799 point cof1 = veh .rotated_center_of_mass();
800 point cof2 = veh2.rotated_center_of_mass();
801 int &x_cof1 = cof1.x;
802 int &y_cof1 = cof1.y;
803 int &x_cof2 = cof2.x;
804 int &y_cof2 = cof2.y;
805 rl_vec2d collision_axis_y;
806
807 collision_axis_y.x = ( veh.global_pos3().x + x_cof1 ) - ( veh2.global_pos3().x + x_cof2 );
808 collision_axis_y.y = ( veh.global_pos3().y + y_cof1 ) - ( veh2.global_pos3().y + y_cof2 );
809 collision_axis_y = collision_axis_y.normalized();
810 rl_vec2d collision_axis_x = collision_axis_y.rotated( M_PI / 2 );
811 // imp? & delta? & final? reworked:
812 // newvel1 =( vel1 * ( mass1 - mass2 ) + ( 2 * mass2 * vel2 ) ) / ( mass1 + mass2 )
813 // as per http://en.wikipedia.org/wiki/Elastic_collision
814 //velocity of veh1 before collision in the direction of collision_axis_y
815 float vel1_y = collision_axis_y.dot_product( velo_veh1 );
816 float vel1_x = collision_axis_x.dot_product( velo_veh1 );
817 //velocity of veh2 before collision in the direction of collision_axis_y
818 float vel2_y = collision_axis_y.dot_product( velo_veh2 );
819 float vel2_x = collision_axis_x.dot_product( velo_veh2 );
820 // e = 0 -> inelastic collision
821 // e = 1 -> elastic collision
822 float e = get_collision_factor( vel1_y / 100 - vel2_y / 100 );
823
824 // Velocity after collision
825 // vel1_x_a = vel1_x, because in x-direction we have no transmission of force
826 float vel1_x_a = vel1_x;
827 float vel2_x_a = vel2_x;
828 // Transmission of force only in direction of collision_axix_y
829 // Equation: partially elastic collision
830 float vel1_y_a = ( m2 * vel2_y * ( 1 + e ) + vel1_y * ( m1 - m2 * e ) ) / ( m1 + m2 );
831 float vel2_y_a = ( m1 * vel1_y * ( 1 + e ) + vel2_y * ( m2 - m1 * e ) ) / ( m1 + m2 );
832 // Add both components; Note: collision_axis is normalized
833 rl_vec2d final1 = collision_axis_y * vel1_y_a + collision_axis_x * vel1_x_a;
834 rl_vec2d final2 = collision_axis_y * vel2_y_a + collision_axis_x * vel2_x_a;
835
836 veh.move.init( final1.as_point() );
837 if( final1.dot_product( veh.face_vec() ) < 0 ) {
838 // Car is being pushed backwards. Make it move backwards
839 veh.velocity = -final1.magnitude();
840 } else {
841 veh.velocity = final1.magnitude();
842 }
843
844 veh2.move.init( final2.as_point() );
845 if( final2.dot_product( veh2.face_vec() ) < 0 ) {
846 // Car is being pushed backwards. Make it move backwards
847 veh2.velocity = -final2.magnitude();
848 } else {
849 veh2.velocity = final2.magnitude();
850 }
851
852 //give veh2 the initiative to proceed next before veh1
853 float avg_of_turn = ( veh2.of_turn + veh.of_turn ) / 2;
854 if( avg_of_turn < .1f ) {
855 avg_of_turn = .1f;
856 }
857
858 veh.of_turn = avg_of_turn * .9;
859 veh2.of_turn = avg_of_turn * 1.1;
860
861 //Energy after collision
862 float E_a = 0.5 * m1 * final1.magnitude() * final1.magnitude() +
863 0.5 * m2 * final2.magnitude() * final2.magnitude();
864 float d_E = E - E_a; //Lost energy at collision -> deformation energy
865 dmg = std::abs( d_E / 1000 / 2000 ); //adjust to balance damage
866 } else {
867 const float m1 = to_kilogram( veh.total_mass() );
868 // Collision is perfectly inelastic for simplicity
869 // Assume veh2 is standing still
870 dmg = std::abs( veh.vertical_velocity / 100 ) * m1 / 10;
871 veh.vertical_velocity = 0;
872 }
873
874 float dmg_veh1 = dmg * 0.5;
875 float dmg_veh2 = dmg * 0.5;
876
877 int coll_parts_cnt = 0; //quantity of colliding parts between veh1 and veh2
878 for( const auto &veh_veh_coll : collisions ) {
879 if( &veh2 == static_cast<vehicle *>( veh_veh_coll.target ) ) {
880 coll_parts_cnt++;
881 }
882 }
883
884 const float dmg1_part = dmg_veh1 / coll_parts_cnt;
885 const float dmg2_part = dmg_veh2 / coll_parts_cnt;
886
887 //damage colliding parts (only veh1 and veh2 parts)
888 for( const auto &veh_veh_coll : collisions ) {
889 if( &veh2 != static_cast<vehicle *>( veh_veh_coll.target ) ) {
890 continue;
891 }
892
893 int parm1 = veh.part_with_feature( veh_veh_coll.part, VPFLAG_ARMOR, true );
894 if( parm1 < 0 ) {
895 parm1 = veh_veh_coll.part;
896 }
897 int parm2 = veh2.part_with_feature( veh_veh_coll.target_part, VPFLAG_ARMOR, true );
898 if( parm2 < 0 ) {
899 parm2 = veh_veh_coll.target_part;
900 }
901
902 epicenter1 += veh.part( parm1 ).mount;
903 veh.damage( parm1, dmg1_part, DT_BASH );
904
905 epicenter2 += veh2.part( parm2 ).mount;
906 veh2.damage( parm2, dmg2_part, DT_BASH );
907 }
908
909 epicenter2.x /= coll_parts_cnt;
910 epicenter2.y /= coll_parts_cnt;
911
912 if( dmg2_part > 100 ) {
913 // Shake vehicle because of collision
914 veh2.damage_all( dmg2_part / 2, dmg2_part, DT_BASH, epicenter2 );
915 }
916
917 if( dmg_veh1 > 800 ) {
918 veh.skidding = true;
919 }
920
921 if( dmg_veh2 > 800 ) {
922 veh2.skidding = true;
923 }
924
925 // Return the impulse of the collision
926 return dmg_veh1;
927}
rl_vec2d face_vec() const
const point & rotated_center_of_mass() const
Definition: vehicle.cpp:3327
rl_vec2d velo_vec() const
float of_turn
Definition: vehicle.h:1931
std::string name() const
Translated name of a part.
Definition: veh_type.cpp:699
#define M_PI
Definition: math_defines.h:21
point as_point() const
Definition: line.cpp:686
rl_vec2d rotated(float angle) const
Definition: line.cpp:647
float magnitude() const
Definition: line.cpp:610
rl_vec2d normalized() const
Definition: line.cpp:620
float y
Definition: point_float.h:13
float x
Definition: point_float.h:12
float dot_product(const rl_vec2d &v) const
Definition: line.cpp:664
@ VPFLAG_ARMOR
Definition: veh_type.h:32
float get_collision_factor(float delta_v)

References _, add_msg(), rl_vec2d::as_point(), c, vehicle::damage(), vehicle::damage_all(), debugmsg, rl_vec2d::dot_product(), DT_BASH, vehicle::face_vec(), get_collision_factor(), vehicle::global_pos3(), tileray::init(), m_bad, M_PI, rl_vec2d::magnitude(), vehicle_part::mount, vehicle::move, vpart_info::name(), vehicle::name, rl_vec2d::normalized(), vehicle::of_turn, vehicle::part(), vehicle::part_info(), vehicle::part_with_feature(), rl_vec2d::rotated(), vehicle::rotated_center_of_mass(), vehicle::skidding, vehicle::sm_pos, units::to_kilogram(), vehicle::total_mass(), vehicle::velo_vec(), vehicle::velocity, vehicle::vertical_velocity, VPFLAG_ARMOR, point::x, tripoint::x, rl_vec2d::x, point::y, tripoint::y, rl_vec2d::y, and tripoint::z.

Referenced by move_vehicle().

◆ vehicle_wheel_traction()

float map::vehicle_wheel_traction ( const vehicle veh,
bool  ignore_movement_modifiers = false 
) const

Definition at line 1567 of file vehicle_move.cpp.

1569{
1570 if( veh.is_in_water( true ) ) {
1571 return veh.can_float() ? 1.0f : -1.0f;
1572 }
1573 if( veh.is_in_water() && veh.is_watercraft() && veh.can_float() ) {
1574 return 1.0f;
1575 }
1576
1577 const auto &wheel_indices = veh.wheelcache;
1578 int num_wheels = wheel_indices.size();
1579 if( num_wheels == 0 ) {
1580 // TODO: Assume it is digging in dirt
1581 // TODO: Return something that could be reused for dragging
1582 return 0.0f;
1583 }
1584
1585 float traction_wheel_area = 0.0f;
1586
1587 if( vehicle_movement::is_on_rails( *this, veh ) ) {
1588 // Vehicles on rails are considered to have all of their wheels on rails
1589 for( int p : veh.rail_wheelcache ) {
1590 traction_wheel_area += veh.cpart( p ).wheel_area();
1591 }
1592 return traction_wheel_area;
1593 }
1594
1595 for( int p : wheel_indices ) {
1596 const tripoint &pp = veh.global_part_pos3( p );
1597 const int wheel_area = veh.cpart( p ).wheel_area();
1598
1599 const auto &tr = ter( pp ).obj();
1600 // Deep water and air
1601 if( tr.has_flag( TFLAG_DEEP_WATER ) || tr.has_flag( TFLAG_NO_FLOOR ) ) {
1602 // No traction from wheel in water or air
1603 continue;
1604 }
1605
1606 int move_mod = move_cost_ter_furn( pp );
1607 if( move_mod == 0 ) {
1608 // Vehicle locked in wall
1609 // Shouldn't happen, but does
1610 return 0.0f;
1611 }
1612
1613 for( const auto &terrain_mod : veh.part_info( p ).wheel_terrain_mod() ) {
1614 if( !tr.has_flag( terrain_mod.first ) ) {
1615 move_mod += terrain_mod.second;
1616 break;
1617 }
1618 }
1619
1620 // Ignore the movement modifier if needed.
1621 if( ignore_movement_modifiers ) {
1622 move_mod = 2;
1623 }
1624
1625 traction_wheel_area += 2.0 * wheel_area / move_mod;
1626 }
1627
1628 return traction_wheel_area;
1629}
bool is_watercraft() const
Definition: vehicle.cpp:4217
std::vector< int > rail_wheelcache
Definition: vehicle.h:1820
bool can_float() const
can_float does the vehicle have freeboard or does it overflow with water?
Definition: vehicle.cpp:4154
std::vector< std::pair< std::string, int > > wheel_terrain_mod() const
Definition: veh_type.cpp:897
bool is_on_rails(const map &m, const vehicle &veh)
Returns whether the vehicle is currently on rails.

References vehicle::can_float(), vehicle::cpart(), vehicle::global_part_pos3(), vehicle::is_in_water(), vehicle_movement::is_on_rails(), vehicle::is_watercraft(), move_cost_ter_furn(), int_id< T >::obj(), vehicle::part_info(), vehicle::rail_wheelcache, ter(), TFLAG_DEEP_WATER, TFLAG_NO_FLOOR, vehicle_part::wheel_area(), vpart_info::wheel_terrain_mod(), and vehicle::wheelcache.

Referenced by vehicle::act_on_map(), and move_vehicle().

◆ vehmove()

void map::vehmove ( )

Definition at line 414 of file map.cpp.

415{
416 // give vehicles movement points
417 VehicleList vehicle_list;
418 int minz = zlevels ? -OVERMAP_DEPTH : abs_sub.z;
419 int maxz = zlevels ? OVERMAP_HEIGHT : abs_sub.z;
420 for( int zlev = minz; zlev <= maxz; ++zlev ) {
421 level_cache &cache = get_cache( zlev );
422 for( vehicle *veh : cache.vehicle_list ) {
423 veh->gain_moves();
424 veh->slow_leak();
426 w.v = veh;
427 vehicle_list.push_back( w );
428 }
429 }
430
431 // 15 equals 3 >50mph vehicles, or up to 15 slow (1 square move) ones
432 // But 15 is too low for V12 death-bikes, let's put 100 here
433 for( int count = 0; count < 100; count++ ) {
434 if( !vehproceed( vehicle_list ) ) {
435 break;
436 }
437 }
438 // Process item removal on the vehicles that were modified this turn.
439 // Use a copy because part_removal_cleanup can modify the container.
440 auto temp = dirty_vehicle_list;
441 for( const auto &elem : temp ) {
442 auto same_ptr = [ elem ]( const struct wrapped_vehicle & tgt ) {
443 return elem == tgt.v;
444 };
445 if( std::find_if( vehicle_list.begin(), vehicle_list.end(), same_ptr ) !=
446 vehicle_list.end() ) {
447 elem->part_removal_cleanup();
448 }
449 }
450 dirty_vehicle_list.clear();
451 // The bool tracks whether the vehicles is on the map or not.
452 std::map<vehicle *, bool> connected_vehicles;
453 for( int zlev = minz; zlev <= maxz; ++zlev ) {
454 level_cache &cache = get_cache( zlev );
455 vehicle::enumerate_vehicles( connected_vehicles, cache.vehicle_list );
456 }
457 for( std::pair<vehicle *const, bool> &veh_pair : connected_vehicles ) {
458 veh_pair.first->idle( veh_pair.second );
459 }
460}
bool vehproceed(VehicleList &vehicle_list)
Definition: map.cpp:462
static void enumerate_vehicles(std::map< vehicle *, bool > &connected_vehicles, const std::set< vehicle * > &vehicle_list)
Use grid traversal to enumerate all connected vehicles.
Definition: vehicle.cpp:4927
void slow_leak()
Definition: vehicle.cpp:5294
void gain_moves()
Definition: vehicle.cpp:5541

References abs_sub, detail::count(), dirty_vehicle_list, vehicle::enumerate_vehicles(), vehicle::gain_moves(), get_cache(), OVERMAP_DEPTH, OVERMAP_HEIGHT, vehicle::slow_leak(), wrapped_vehicle::v, level_cache::vehicle_list, vehproceed(), tripoint::z, and zlevels.

Referenced by game::do_turn().

◆ vehproceed()

bool map::vehproceed ( VehicleList vehicle_list)

Definition at line 462 of file map.cpp.

463{
464 wrapped_vehicle *cur_veh = nullptr;
465 float max_of_turn = 0;
466 // First horizontal movement
467 for( wrapped_vehicle &vehs_v : vehicle_list ) {
468 if( vehs_v.v->of_turn > max_of_turn ) {
469 cur_veh = &vehs_v;
470 max_of_turn = cur_veh->v->of_turn;
471 }
472 }
473
474 // Then vertical-only movement
475 if( cur_veh == nullptr ) {
476 for( wrapped_vehicle &vehs_v : vehicle_list ) {
477 if( vehs_v.v->is_falling || ( vehs_v.v->is_rotorcraft() && vehs_v.v->get_z_change() != 0 ) ) {
478 cur_veh = &vehs_v;
479 break;
480 }
481 }
482 }
483
484 if( cur_veh == nullptr ) {
485 return false;
486 }
487
488 cur_veh->v = cur_veh->v->act_on_map();
489 if( cur_veh->v == nullptr ) {
490 vehicle_list = get_vehicles();
491 }
492
493 // confirm that veh_in_active_range is still correct for each z-level
494 int minz = zlevels ? -OVERMAP_DEPTH : abs_sub.z;
495 int maxz = zlevels ? OVERMAP_HEIGHT : abs_sub.z;
496 for( int zlev = minz; zlev <= maxz; ++zlev ) {
497 level_cache &cache = get_cache( zlev );
498
499 // Check if any vehicles exist in the active range for this z-level
501 std::any_of( std::begin( cache.veh_exists_at ),
502 std::end( cache.veh_exists_at ), []( const auto & row ) {
503 return std::any_of( std::begin( row ), std::end( row ), []( bool veh_exists ) {
504 return veh_exists;
505 } );
506 } );
507 }
508
509 return true;
510}
vehicle * act_on_map()

References abs_sub, vehicle::act_on_map(), get_cache(), get_vehicles(), vehicle::of_turn, OVERMAP_DEPTH, OVERMAP_HEIGHT, wrapped_vehicle::v, level_cache::veh_exists_at, level_cache::veh_in_active_range, tripoint::z, and zlevels.

Referenced by vehmove().

◆ vertical_shift()

void map::vertical_shift ( int  newz)

Moves the map vertically to (not by!) newz.

Does not actually shift anything, only forces cache updates. In the future, it will either actually shift the map or it will get removed after 3D migration is complete.

Definition at line 6922 of file map.cpp.

6923{
6924 if( !zlevels ) {
6925 debugmsg( "Called map::vertical_shift in a non-z-level world" );
6926 return;
6927 }
6928
6929 if( newz < -OVERMAP_DEPTH || newz > OVERMAP_HEIGHT ) {
6930 debugmsg( "Tried to get z-level %d outside allowed range of %d-%d",
6931 newz, -OVERMAP_DEPTH, OVERMAP_HEIGHT );
6932 return;
6933 }
6934
6935 tripoint trp = get_abs_sub();
6936 set_abs_sub( tripoint( trp.xy(), newz ) );
6937
6938 // TODO: Remove the function when it's safe
6939 return;
6940}

References debugmsg, get_abs_sub(), OVERMAP_DEPTH, OVERMAP_HEIGHT, set_abs_sub(), tripoint::xy(), and zlevels.

Referenced by game::vertical_shift().

◆ water_from()

item map::water_from ( const tripoint p)

Definition at line 4386 of file map.cpp.

4387{
4388 if( has_flag( "SALT_WATER", p ) ) {
4390 }
4391
4392 const ter_id terrain_id = ter( p );
4393 if( terrain_id == t_sewage ) {
4395 ret.poison = rng( 1, 7 );
4396 return ret;
4397 }
4398
4400 // iexamine::water_source requires a valid liquid from this function.
4401 if( terrain_id.obj().examine == &iexamine::water_source ) {
4402 int poison_chance = 0;
4403 if( terrain_id.obj().has_flag( TFLAG_DEEP_WATER ) ) {
4404 if( terrain_id.obj().has_flag( TFLAG_CURRENT ) ) {
4405 poison_chance = 20;
4406 } else {
4407 poison_chance = 4;
4408 }
4409 } else {
4410 if( terrain_id.obj().has_flag( TFLAG_CURRENT ) ) {
4411 poison_chance = 10;
4412 } else {
4413 poison_chance = 3;
4414 }
4415 }
4416 if( one_in( poison_chance ) ) {
4417 ret.poison = rng( 1, 4 );
4418 }
4419 return ret;
4420 }
4421 if( furn( p ).obj().examine == &iexamine::water_source ) {
4422 return ret;
4423 }
4424 return item();
4425}
static const int INFINITE_CHARGES
Definition: item.h:2155
void examine(Character &p, const tripoint &pos)
Calls the examine function of furniture or terrain at given tile, for given character.
Definition: map.cpp:1620
@ TFLAG_CURRENT
Definition: mapdata.h:302
void water_source(player &p, const tripoint &examp)
Definition: iexamine.cpp:3841

References examine(), map_data_common_t::examine, furn(), map_data_common_t::has_flag(), has_flag(), item::INFINITE_CHARGES, int_id< T >::obj(), one_in(), cata::hash64_detail::ret, rng(), calendar::start_of_cataclysm, t_sewage, ter(), TFLAG_CURRENT, TFLAG_DEEP_WATER, and iexamine::water_source().

Referenced by inventory::form_from_map(), use_amount_square(), use_charges(), and iexamine::water_source().

Friends And Related Function Documentation

◆ editmap

friend class editmap
friend

Definition at line 385 of file map.h.

◆ visitable< map_cursor >

friend class visitable< map_cursor >
friend

Definition at line 385 of file map.h.

Member Data Documentation

◆ abs_sub

tripoint map::abs_sub
protected

Absolute coordinates of first submap (get_submap_at(0,0)) This is in submap coordinates (see overmapbuffer for explanation).

It is set upon:

  • loading submap at grid[0],
  • generating submaps (generate)
  • shifting the map with shift

Definition at line 1844 of file map.h.

Referenced by add_item(), add_item_or_charges(), add_vehicle(), adjust_radiation(), apply_faction_ownership(), bash_rating(), bash_resistance(), bash_strength(), build_floor_caches(), can_put_items(), can_put_items_ter_furn(), check_submap_active_item_consistency(), clear_vehicle_cache(), create_anomaly(), decay_fields_and_scent(), detach_vehicle(), draw_fill_background(), draw_lab(), draw_mine(), draw_temple(), draw_triffid(), features(), furn(), furn_set(), furnname(), generate(), get_abs_sub(), get_active_items_in_radius(), get_nonant(), get_submap_at(), get_vehicles(), getabs(), getlocal(), has_flag(), has_flag_furn(), has_flag_ter(), has_flag_ter_or_furn(), has_furn(), i_at(), i_clear(), i_rem(), is_bashable(), is_bashable_furn(), is_bashable_ter(), is_bashable_ter_furn(), is_divable(), is_outside(), is_water_shallow_current(), loadn(), make_active(), move_cost(), move_cost_ter_furn(), name(), passable(), place_items(), place_npc(), place_vending(), points_on_zlevel(), process_fields(), process_fields_in_submap(), process_items(), reset_vehicle_cache(), rotate(), save(), saven(), scent_blockers(), set_abs_sub(), set_radiation(), set_temperature(), spawn_an_item(), spawn_item(), spawn_items(), spawn_monsters(), spawn_monsters_submap(), spawn_monsters_submap_group(), ter(), ter_set(), tername(), update_submap_active_item_status(), update_visibility_cache(), vehmove(), and vehproceed().

◆ caches

std::array< std::unique_ptr<level_cache>, OVERMAP_LAYERS > map::caches
private

Holds caches for visibility, light, transparency and vehicles.

Definition at line 2016 of file map.h.

Referenced by access_cache(), get_cache(), get_cache_ref(), and map().

◆ dirty_vehicle_list

◆ field_furn_locs

std::vector<tripoint> map::field_furn_locs
private

Vector of tripoints containing active field-emitting furniture.

Definition at line 2012 of file map.h.

Referenced by actualize(), furn_set(), get_furn_field_locations(), load(), and shift_traps().

◆ grid

std::vector<submap *> map::grid
private

The list of currently loaded submaps.

The size of this should not be changed. After calling load or generate, it should only contain non-null pointers. Use getsubmap or setsubmap to access it.

Definition at line 2001 of file map.h.

Referenced by actualize(), add_roofs(), clear_spawns(), clear_traps(), editmap::cleartmpmap(), displace_vehicle(), getsubmap(), loadn(), map(), saven(), and setsubmap().

◆ last_full_vehicle_list

VehicleList map::last_full_vehicle_list
private

Vehicle list doesn't change often, but is pretty expensive.

Definition at line 2032 of file map.h.

Referenced by get_vehicles().

◆ last_full_vehicle_list_dirty

bool map::last_full_vehicle_list_dirty = true
private

◆ max_populated_zlev

cata::optional<std::pair<tripoint, int> > map::max_populated_zlev = cata::nullopt
private

Definition at line 2046 of file map.h.

Referenced by calc_max_populated_zlev(), and invalidate_max_populated_zlev().

◆ my_MAPSIZE

◆ pathfinding_caches

std::array< std::unique_ptr<pathfinding_cache>, OVERMAP_LAYERS > map::pathfinding_caches
mutableprivate

Definition at line 2018 of file map.h.

Referenced by get_pathfinding_cache(), get_pathfinding_cache_ref(), and map().

◆ skew_vision_cache

lru_cache<point, char> map::skew_vision_cache
mutableprivate

Cache of coordinate pairs recently checked for visibility.

Definition at line 2027 of file map.h.

Referenced by build_map_cache(), and sees().

◆ submaps_with_active_items

std::set<tripoint> map::submaps_with_active_items
private

◆ support_cache_dirty

std::set<tripoint> map::support_cache_dirty
private

Definition at line 1552 of file map.h.

Referenced by process_falling(), shift(), support_dirty(), and ter_set().

◆ traplocs

std::vector< std::vector<tripoint> > map::traplocs
private

This vector contains an entry for each trap type, it has therefor the same size as the traplist vector.

Each entry contains a list of all point on the map that contain a trap of that type. The first entry however is always empty as it denotes the tr_null trap.

Definition at line 2008 of file map.h.

Referenced by actualize(), clear_traps(), load(), map(), remove_trap(), shift_traps(), ter_set(), trap_locations(), and trap_set().

◆ visibility_variables_cache

visibility_variables map::visibility_variables_cache
private

Definition at line 2042 of file map.h.

Referenced by get_visibility_variables_cache(), and update_visibility_cache().

◆ vision_transparency_cache

vision_adjustment map::vision_transparency_cache[8] = { VISION_ADJUST_NONE }
protected

Definition at line 1834 of file map.h.

Referenced by apply_vision_transparency_cache(), and build_vision_transparency_cache().

◆ zlevels


The documentation for this class was generated from the following files: